1. Installation
First, go to http://nodejs.org to download and install. The version I downloaded is 0.8.14. Installation is very simple, just take the next step. Then configure the installation directory in the path, and msi will install npm (Node Package Manager) together.
My installation directory is C:Program Files (x86)nodejs. At this time, use the cmd command window node -v
and the npm -v
command to check the installed version
1.1, helloworld
Create a new file hello.js in the Node.js project directory and type a line of code in it
console.log('hello, nodejs.') ;
Enter the command line console, enter the Node.js project directory and type node hello.js
The console output "hello, nodejs."
1.2, web version of helloworld
Create a new http.js in the Node.js project directory, the code is as follows
var http = require("http"); http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/html"}); response.write("Hello World!"); response.end(); }).listen(8000);
Start the service in the command line and type node http.js
Then open the browser address bar and enter http://localhost:8000/. When you see Hello World! output on the page, it is successful.
The version of node.js must be synchronized with the API
The version numbers of node.js are regular. Even-numbered versions are stable versions, and odd-numbered versions are unstable versions
2 HelloWorld code analysis
Okay, let’s analyze our HelloWorld line by line from now on.
Introduction module
var http = require("http");
The require method is used to introduce a module, and the parameter is the name of the module. For example, the File System module can be introduced like this:
var fs = require("fs");
We can use the require() method as a global method, but in fact it is more like a local method belonging to a certain module. Its documentation is here: https://nodejs.org/api/globals.html.
The require method returns an instance of a certain module. For example, require("http") returns an HTTP instance. The reference documentation for HTTP examples is here: https://nodejs.org/api/http.html.
We see that the HTTP module has a method createServer(), which involves our second line of code.
Create Server
The createServer() method of the HTTP module accepts a method as a parameter, and the prototype is:
http.createServer([requestListener])
requestListener is a method that is associated with the request event of the http.Server class. In this way, when the client request arrives, the requestListener will be called.
requestListener has two parameters, and the function prototype is as follows:
function (request, response) { }
The type of the first parameter request is http.IncomingMessage
, which implements the Readable Stream
interface.
The type of the second parameter is http.ServerResponse
, which implements the Writeable Stream
interface.
Stream’s API is here: https://nodejs.org/api/stream.html. At the same time, request and response are also EventEmitters, which can emit specific events.
The API of EventEmitter is here: https://nodejs.org/api/events.html#events_class_events_eventemitter. Later we will talk about how to use EventEmitter to emit and process events.
Let’s review the code we created the server:
http.createServer( function(request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World!"); response.end(); } ).listen(8000);
http.createServer returns an http.Server instance. The listen method of http.Server allows the server to listen on a certain port, which is 8000 in the example.
As you can see, we provide an anonymous function to the createServer method. In this method, we write back the "Hello World!" message to the client through the response parameter.
Analyze client requests
We analyzed the http.createServer method earlier. Its parameter is a method with two parameters, one representing the request sent by the client, and the other representing the response to be written back to the client. Let's take a look at the request parameters.
request is an instance of http.IncomingMessage
. Through this instance, we can get the request parameters, such as HTTP method, HTTP version, url, header, etc. The specific API is here: https://nodejs.org/api /http.html#http_http_incomingmessage.
Let’s take a look by modifying HelloWorld.js (save as HelloWorld2.js). The code is as follows:
// 引入http模块 var http = require("http"); // 创建server,指定处理客户端请求的函数 http.createServer( function(request, response) { console.log("method - " + request.method); console.log("version - " + request.httpVersion); console.log("url - " + request.url); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World!"); response.end(); } ).listen(8000); console.log("Hello World start listen on port 8000");
如你所见,我使用console这个对象来输出了一些调试信息,打印了HTTP方法、版本、url等信息。可以执行node HelloWorld2.js,浏览器访问http://localhost:8000,然后跑到命令行看看输出了什么信息,我这里是这样的:
我们简简单单的HelloWorld已经可以发送一些响应数据给客户端,你在浏览器里能看到“Hello World!”字样。这个响应是通过http.ServerResponse
的实例response
发送给客户端的。
http.ServerResponse
也是一个Stream
,还是一个EventEmitter。我们通过它给客户度返回HTTP状态码、数据、HTTP头部等信息。
HTTP模块
在Node.js的HTTP模块,状态行就是通过http.ServerResponse的writeHead方法写给客户端的。writeHead方法原型如下:
response.writeHead(statusCode[, statusMessage][, headers])
这个方法的第一个参数,就是statusCode,也就是200、403之类的数字,剩下的参数是可选的。最后一个参数是headers,你可以在这里使用JSON对象表示法来写一些HTTP头部,比如:{“Content-Type”:”text/plain”,”Content-Length”:11}
。第一个可选参数statusMessage用来指定一个状态描述消息,可以不填写。
HTTP头部
头部就是一些key-value对,比如我们在HelloWorld里看到的”Content-Type”,就是用来说明数据类型的头部标签,对应的可能是文本文件、图片、视频、二进制等。类似的还有”Content-Length”,用来指定数据长度。还有很多很多,比如”Date”、”Connection”等。具体还是参考前面的链接吧。
头部还可以使用http.ServerResponse的response.setHeader(name, value)
方法来单独设置,一次可以设置一个HTTP头部。
数据
头部之后就是数据了,有些状态码,比如200,后续都会有一些数据。而有些,比如301、404、403、500之类的,多数没有数据。
数据通过http.ServerResponse的write方法来写回给客户端,比如这样:
response.setHeader("Content-Type", "text/html");
这里要提一点,HTTP常见的数据传输编码方式有两种:
设置Content-Length,传输固定长度的数据设置Transfer-Encoding头部为chunked,分块传输数据
像我们现在的HelloWorld示例,没有设置Content-Length头部,Node.js的HTTP模块就默认为chunked编码。
我们使用Chrome浏览器的开发者工具来查看网络数据,可以很明确的看到。如下图所示:
HTTP响应
我标注出来的三处,都是HelloWorld示例传递给浏览器的HTTP头部信息。
我们通过http.ServerResponse的write方法向客户端写数据。你可以一次写入所有数据,也可以把数据分开来多次写入。当要传输的数据量较大时,分多次写入就是比较合理的做法,比如你向客户端发送大文件,就比较适合分多次写入,也可以利用Node.js的异步特性,获得不错的性能。