一、简介
1、Node.js标准库提供了http模块,其中封装了一个HTTP服务器。
2、http.Server是http模块中的一个基于事件的HTTP服务器对象,用Node.js做的所有基于HTTP协议的系统都是基于该对象实现的。
二、创建一个简单的服务器
1、实现一个简单的服务器代码如下,其中http.createServer就是创建了一个http.Server实例,并将一个函数传入作为HTTP请求的处理函数,该函数的两个参数分别是请求对象和响应对象,其中writeHead是写入响应头,write是写入响应体,end是结束并发送。最后调用listen函数启动服务器并监听3000端口。
var http = require('http'); http.createServer(function(req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.write('<h1>Node.js</h1>'); res.end('<p>Hello World</p>'); }).listen(3000); console.log("HTTP server is listening at port 3000.");
三、http.Server事件
1、所有的请求都被封装为独立的事件,只需要对它的事件编写响应函数即可实现HTTP服务器的所有功能。http.Server继承自EventEmitter。
2、request事件:当客户端请求到来时,该事件被触发,提供两个参数req和res,分别是http.ServerRequest和http.ServerResponse的实例,表示请求和响应信息。对于该事件,Node.js提供了一个使用捷径,即如上代码的使用方式(http.createServer([requestListener])),创建一个HTTP服务器并将requestListener作为request事件的监听函数,事实上它显式的实现方法如下:
var http = require('http'); var server = new http.Server(); server.on('request', function(req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.write('<h1>Node.js</h1>'); res.end('<p>Hello World</p>'); }); server.listen(3000); console.log("HTTP server is listening at port 3000.");
3、connection事件:当TCP连接建立时,该事件被触发,提供一个参数socket,为net.Socket 的实例。connection事件的粒度要大于request,因为客户端在Keep-Alive模式下可能会在同一个连接内发送多次请求。
4、close事件:当服务器关闭时,该事件被触发。注意不是在用户连接断开时。
5、其他事件:checkContinue、upgrade、clientError事件。
四、http.ServerRequest对象
1、http.ServerRequest是HTTP请求的信息,一般由http.Server的request事件发送,作为第一个参数传递,通常简称request或req,如创建简单服务器中的代码的处理函数的第一个参数所示。
2、因为请求体可能较长,需要一定的时间传输,所以该对象提供了一些事件来控制请求体传输。
3、data事件:当请求体数据到来时,该事件被触发。该事件提供一个参数chunk,表示接收到的数据。如果该事件没有被监听,那么请求体将会被抛弃。该事件可能会被调用多次。
4、end事件:当请求体数据传输完成时,该事件被触发,此后将不会再有数据到来。
5、close事件:用户当前请求结束时,该事件被触发。不同于 end,如果用户强制终止了传输,也还是调用close。
6、data事件和on事件例子参考下面的获取post参数例子。
7、此外,该对象还包括一些属性,如下图。
8、获取GET请求内容:可以手动解析后面的内容作为GET请求的参数。Node.js的url模块中的parse函数提供了这个功能,如下图:通过url.parse,原始的path被解析为一个对象。
9、获取POST请求内容:POST请求的内容全部都在请求体中,Node.js默认是不会解析请求体的,实现方法如下:并没有在请求响应函数中向客户端返回信息,而是定义了一个post变量,用于在闭包中暂存请求体的信息。通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中。在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。注意:不要在真正的生产应用中使用上面这种简单的方法来获取POST请求,因为它有严重的效率问题和安全问题。
var http = require('http'); var querystring = require('querystring'); var util = require('util'); http.createServer(function(req, res) { var post = ''; req.on('data', function(chunk) { post += chunk; }); req.on('end', function() { post = querystring.parse(post); res.end(util.inspect(post)); }); }).listen(3000);
五、http.ServerResponse对象
1、http.ServerResponse是返回给客户端的信息,它也是由http.Server的request事件发送的,作为第二个参数传递,一般简称为response或res。如创建简单服务代码中处理函数的第二个参数。
2、方法response.writeHead(statusCode, [headers]):向请求的客户端发送响应头,其中statusCode是HTTP状态码,headers是一个类似关联数组的对象,表示响应头的每个属性。该函数在一个请求内最多只能调用一次,如果不调用,则会自动生成一个响应头。如创建简单服务器中处理函数的第一条语句。
3、方法response.write(data, [encoding]):向请求的客户端发送响应内容。data是一个Buffer或字符串,表示要发送的内容。如果data是字符串,那么需要指定encoding来说明它的编码方式,默认是utf-8。在response.end调用之前,response.write可以被多次调用。如创建简单服务器中处理函数的第二条语句。
4、方法response.end([data], [encoding]):结束响应,告知客户端所有发送已经完成。当所有要返回的内容发送完毕的时候,该函数必须被调用一次。它接受两个可选参数,意义和response.write相同。如果不调用该函数,客户端将永远处于等待状态。如创建简单服务器中处理函数的第三条语句。