返回的内容包括:状态代码/状态描述信息、响应头部、响应主体。下文会举几个简单的例子。

例子

在下面的例子中,我们同时设置了 状态代码/状态描述信息、响应头部、响应主体,就是这么简单。

  1. var http = require('http');
  2. // 设置状态码、状态描述信息、响应主体
  3. var server = http.createServer(function(req, res){
  4. res.writeHead(200, 'ok', {
  5. 'Content-Type': 'text/plain'
  6. });
  7. res.end('hello');
  8. });
  9. server.listen(3000);

res提供了 res.writeHead()、res.statusCode/res.statusMessage 来实现这个目的。

举例,如果想要设置 200/ok ,可以

  1. res.writeHead(200, 'ok');

也可以

  1. res.statusCode = 200;
  2. res.statusMessage = 'ok';

两者差不多,差异点在于

  1. res.writeHead() 可以提供额外的功能,比如设置响应头部。
  2. 当响应头部发送出去后,res.statusCode/res.statusMessage 会被设置成已发送出去的 状态代码/状态描述信息。

res提供了 res.writeHead()、response.setHeader() 来实现响应头部的设置。

举例,比如想把 Content-Type 设置为 text-plain,那么可以

两者的差异点在哪里呢?

  1. res.writeHead() 不单单是设置header。
  2. 已经通过 res.setHeader() 设置了header,当通过 res.writeHead() 设置同名header,res.writeHead() 的设置会覆盖之前的设置。
  1. var http = require('http');
  2. var server = http.createServer(function(req, res){
  3. res.setHeader('Content-Type', 'text/html');
  4. res.writeHead(200, 'ok', {
  5. });
  6. });
  7. server.listen(3000);

而下面的例子,则直接报错。报错信息为 Error: Can't set headers after they are sent.

  1. var http = require('http');
  2. var server = http.createServer(function(req, res){
  3. res.writeHead(200, 'ok', {
  4. 'Content-Type': 'text/plain'
  5. });
  6. res.setHeader('Content-Type', 'text/html');
  7. res.end('hello');
  8. });
  9. server.listen(3000);

增、删、改、查 是配套的。下面分别举例说明下,例子太简单就直接上代码了。

  1. // 增
  2. res.setHeader('Content-Type', 'text/plain');
  3. // 删
  4. res.removeHeader('Content-Type');
  5. // 改
  6. res.setHeader('Content-Type', 'text/plain');
  7. res.setHeader('Content-Type', 'text/html'); // 覆盖
  8. // 查
  9. res.getHeader('content-type');

其中略显不同的是 res.getHeader(name),name 用的是小写,返回值没做特殊处理。

此外,还有不那么常用的:

  • res.headersSent:header是否已经发送;
  • res.sendDate:默认为true。但为true时,会在response header里自动设置Date首部。

主要用到 res.write() 以及 res.end() 两个方法。

res.write() API的信息量略大,建议看下官方文档

  • chunk:响应主体的内容,可以是string,也可以是buffer。当为string时,encoding参数用来指明编码方式。(默认是utf8)
  • encoding:编码方式,默认是 utf8。
  • callback:当响应体flushed时触发。(TODO 这里想下更好的解释。。。)

使用上没什么难度,只是有些注意事项:

  1. 如果 res.write() 被调用时, res.writeHead() 还没被调用过,那么,就会把header flush出去。
  2. res.write() 可以被调用多次。

掌握了 res.write() 的话,res.end() 就很简单了。res.end() 的用处是告诉nodejs,header、body都给你了,这次响应就到这里吧。

  1. res.write(data, encoding);

chunk数据

参考这里:http://stackoverflow.com/questions/6258210/how-can-i-output-data-before-i-end-the-response

也就是说,除了nodejs的特性,还需要了解 HTTP协议、浏览器的具体实现。(细思极恐)

如果是 text/html

  1. var http = require('http');
  2. http.createServer(function(req, res) {
  3. res.setHeader('Content-Type', 'text/html; charset=utf-8');
  4. res.write('hello');
  5. setTimeout(function() {
  6. res.write(' world!');
  7. res.end();
  8. }, 2000);
  9. }).listen(3000);

如果是 text/plain

  1. var http = require('http');
  2. http.createServer(function (req, res) {
  3. res.writeHead(200, {
  4. 'Content-Type': 'text/plain; charset=utf-8',
  5. 'X-Content-Type-Options': 'nosniff'
  6. });
  7. res.write('hello');
  8. setTimeout(function(){
  9. res.write('world');
  10. res.end()
  11. }, 2000);

失败例子

接口:response.setTimeout(msecs, callback)

关于 timeout 事件的说明,同样是言简意赅(WTF),话少信息量大,最好来个demo TODO

If no ‘timeout’ listener is added to the request, the response, or the server, then sockets are destroyed when they time out. If you assign a handler on the request, the response, or the server’s ‘timeout’ events, then it is your responsibility to handle timed out sockets.

事件 close/finish

  • close:response.end() 被调用前,连接就断开了。此时会触发这个事件。
  • finish:响应header、body都已经发送出去(交给操作系统,排队等候传输),但客户端是否实际收到数据为止。(这个事件后,res 上就不会再有其他事件触发)
  • response.finished:一开始是false,响应结束后,设置为true。
  • response.sendDate:默认是true。是否自动设置Date头部。(按HTTP协议是必须要的,除非是调试用,不然不要设置为false)
  • response.headersSent:只读属性。响应头部是否已发送。
  • response.writeContinue():发送 HTTP/1.1 100 Continue 消息给客户端,提示说服务端愿意接受客户端的请求,请继续发送请求正文(body)。(TODO 做个demo啥的是大大的好)

相关链接

How can I output data before I end the response?