详解Node.js的http模块之HTTP服务端介绍

 2015年08月26日    303     声明


Node.js的http模块,封装了一个高效的HTTP服务器对象http.Serverhttp.createServerhttp模块创建HTTP服务器对象的工厂方法,Node.js所有基于HTTP协议系统,都是基于此对象实现。http.Server以伪类的形式实现了HTTP服务器,该类继承自net.Server的TCP服务器,net.Server中的内容均能在http.Server中使用。

  1. http.createServer([requestListener])创建HTTP服务器
  2. 类:http.Server服务器对象
  3. 类:http.ServerResponse服务器响应对象
  4. 类:http.IncomingMessage客户端请求对象


1. http.createServer([requestListener])创建HTTP服务器

http.createServer方法会返回一个http.Server对象实例,requestListener可选参数传入时,将做为http.Server对象'request'事件的监听器。


2. 类:http.Server服务器对象

http.Server对象是一个EventEmitter,在其事件监听器中也会创建一些对象,如:'request'事件会创建http.IncomingMessagehttp.ServerResponse


2.1 http.Server中的事件

事件:'request',其监听函数格式为function (request, response) { }

每收到一个客户端请求时触发,注意每个连接又可能有多个请求(在keep-alive连接中)。requesthttp.IncomingMessage的一个实例;responsehttp.ServerResponse的一个实例。

事件:'connection',其监听函数格式为function (socket) { }

新的TCP流建立时触发。 socket是一个net.Socket对象。 通常用户无需处理该事件。除事件监听外,还可以通过request.connection访问socket

事件:'close',其监听函数格式为function () { } ,当此服务器关闭时触发。

事件:'checkContinue',其监听函数格式为function (request, response) { }

每当收到Expect: 100-continueHTTP请求时触发。如果未监听该事件,服务器会酌情自动发送100 Continue响应。

事件:'connect',其监听函数格式为function (request, socket, head) { }

每当客户端发起CONNECT请求时触发。如果未监听该事件,客户端发起CONNECT请求时连接会被关闭。

  • request 是HTTP请求的参数,与request事件参数相同。
  • socket 是服务器和客户端间的socket
  • head 是一个Buffer的实例。网络隧道的第一个包,可能为空。

事件:'upgrade',其监听函数格式为function (request, socket, head) { }

每当一个客户端请求HTTP版本升级时,该事件会被触发。如果这个事件没有被监听,那么这些请求升级的客户端的连接将会被关闭。参数与connect参数相同。

事件:'clientError',其监听函数格式为function (exception, socket) { }

当客户端连接触发了一个'error'事件时,事件会被传送到这里.


2.2 http.Server中的方法

server.listen(port[, hostname][, backlog][, callback])

在指定的主机名(hostname)端口(port)开始接收连接。如果省略主机名,服务器会接收指向任意IPv4地址的链接(INADDR_ANY)。

backlog积压量,为连接等待队列的最大长度。实际长度由操作系统通过sysctl设置决定,如:Linux上的 tcp_max_syn_backlogsomaxconn,该参数缺省值为 511(不是 512)。

server.listen(path, [callback])

在一个UNIX Socket套接字服务器所在路径path开始接收连接。当监听对象为UNIX Socket套接字时,需要提供一个文件名而不是端口号和主机名。

server.listen(handle[, callback])

从文件描述符handle开始接收连接。handle变量可以被设置为server或者socket(任一以下划线开头的成员 _handle), 或者一个 {fd: }对象。Windows不支持监听文件描述符。

server.close([callback])

服务器停止接收新的连接,保持现有连接。当所有连接结束的时候服务器会关闭,并会触发 'close' 事件。

server.setTimeout(msecs, callback)

设置Socket套接字的超时时间,单位msecs为秒。如果一个超时发生,那么Server对象上会分发一个'timeout'事件,同时将套接字作为参数传递。Server默认超时时间为 2 分钟,如果超时将会销毁Socket,如果给 Server的'timeout'事件设置了回调函数,那么Socket超时会被该函数处理。


2.3 http.Server中的属性

server.maxHeadersCount

最大请求头的数量限制,默认 1000。如果设置为 0,则不做任何限制。

server.timeout

Socket套接字被判断为超时时间,单位为毫秒,默认 12000(2分钟)。设置为 0后,则不受超时限制。注意:修改此项只会对新连接产生影响。


3. 类:http.ServerResponse服务器响应对象

http.ServerResponse是一个由http.Server创建的对象,在触发'request'事件后,做事件回调函数的第二个参数传递给回调函数。http.ServerResponse实现了Writable Stream接口,它还是一个EventEmitter

3.1 http.ServerResponse中的事件

事件:'close',其监听函数格式为function () { }

在调用response.end(),或准备flush前触发,触发后底层连接结束。

事件:'finish',其监听函数格式为function () { }

发送完响应后(服务器响应完成)触发。响应头和响应体最后一段数据离开操作系统,通过网络来传输时被触发,这并不代表客户端已经收到数据。 这个事件之后,http.ServerResponse不会再触发任何事件。


3.2 http.ServerResponse中的方法

response.writeContinue()

发送HTTP/1.1 100 Continue消息给客户端,表示请求体可以发送,会触发http.Server'checkContinue' 事件。

response.writeHead(statusCode[, statusMessage][, headers])

向客户端请求发送一个响应头。statusCode状态码是 3 位数字,如:404。可通过statusMessage设置状态消息。最后一个参数headers是响应头。

这个方法在当前请求中仅能调用一次,而且必须在response.end()前调用

var body = 'itbilu.com ';
response.writeHead(200, 'OK', {
  'Content-Length': body.length,
  'Content-Type': 'text/plain' });

response.setHeader(name, value)

为默认或者已存在的头设置一条单独的头内容。如果这个头已经存在于,将会覆盖原来的内容。如果想设置多个值, 就使用一个相同名字的字符串数组。

response.setHeader("Content-Type", "text/html");
response.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);

response.getHeader(name)

读取一个在队列中但是还没有被发送至客户端的header。名字是大小写敏感。仅能再头被flushed前调用

response.removeHeader(name)

移除一个在队列中但是还没有被发送至客户端的header

response.setTimeout(msecs, callback)

设置Socket套接字的超时时间,单位msecs为秒。如果提供了回调函数,其将会做为响应对象的'timeout'事件的监听器。

response.addTrailers(headers)

添加HTTP尾随headers(一个在消息末尾的header)给响应。只有当数据块编码被用于响应时尾随才会被触发,如果不是他们将会被自动丢弃。如果你想触发http.IncomingMessage'trailers'事件, HTTP会要求发送Trailer头。

response.write(chunk, [encoding])

向响应流发送一个数据块。这个方法可能被调用多次,以提供响应体内容。如果调用了这个方法,但还没有调用response.writeHead(),将会向响应体提供默认的header

参数chunk可以是字符串或者Buffer缓存。如果chunk是一个字符串, 第二个参数encoding表示这个字符串的编码方式,默认为'utf8'

第一次调用response.write()时,将会发送缓存的header信息和第一个报文给客户端。 第二次调用response.write()时,Node会假设你将发送数据流,然后分别地发送。这意味着响应 头header是缓存到第一次报文的数据块中。

如果所有数据被成功刷新到内核缓冲区,则返回true。如果所有或部分数据在用户内存里还处于队列中,则返回false。当缓冲区再次被释放时,'drain'事件会被触发。

response.end([data], [encoding])

当所有的响应报头和报文被发送完成时这个方法将信号发送给服务器,服务器会认为这个消息完成了。 每次响应完成之后必须调用该方法。

如果指定了参数data,就相当于先调用response.write(data, encoding)再调用 response.end()


3.3 http.ServerResponse中的属性

response.statusCode

当使用默认header时(没有显式地调用 response.writeHead()来修改header),这个属性决定header更新时被传回客户端的HTTP状态码。当响应头已经被发送回客户端,那么这个属性则表示已经被发送出去的状态码。

response.headersSent

Boolean值(只读),如果headers发送完毕,则为true,否则为false

response.sendDate

默认值为true。若为true,当 headers里没有Date值时,自动生成 Date并发送。只有在测试环境才能禁用,因为HTTP要求响应包含Date头。


4. 类:http.IncomingMessage客户端请求对象

详见:http.IncomingMessage