Node.js v6.10.1 文档


目录

http#

查看英文版 / 参与翻译

稳定性: 2 - 稳定的

使用 HTTP 服务器和客户端必须 require('http')

Node.js 中的 HTTP 接口被设计为支持以往较难使用的协议的许多特性。 比如,大块编码的消息。 该接口从不缓存整个请求或响应,所以用户能够流化数据。

HTTP 消息头由类似以下的对象表示:

{ 'content-length': '123',
  'content-type': 'text/plain',
  'connection': 'keep-alive',
  'host': 'mysite.com',
  'accept': '*/*' }

键名是小写的,值是不能修改的。

为了支持全部可能的 HTTP 应用,Node.js 的 HTTP API 是非常底层的。 它只涉及流处理和消息解析。 它把一个消息解析成头部和主体,但它不解析具体的头部或主体。

详见 message.headers 了解如何处理重复的头部。

收到的原始消息头保存在 rawHeaders 属性中,它是一个 [key, value, key2, value2, ...] 的数组。 例如,上面的消息头对象可能有一个类似以下的 rawHeaders 列表:

[ 'ConTent-Length', '123456',
  'content-LENGTH', '123',
  'content-type', 'text/plain',
  'CONNECTION', 'keep-alive',
  'Host', 'mysite.com',
  'accepT', '*/*' ]

http.Agent 类#

查看英文版 / 参与翻译

An Agent is responsible for managing connection persistence and reuse for HTTP clients. It maintains a queue of pending requests for a given host and port, reusing a single socket connection for each until the queue is empty, at which time the socket is either destroyed or put into a pool where it is kept to be used again for requests to the same host and port. Whether it is destroyed or pooled depends on the keepAlive option.

Pooled connections have TCP Keep-Alive enabled for them, but servers may still close idle connections, in which case they will be removed from the pool and a new connection will be made when a new HTTP request is made for that host and port. Servers may also refuse to allow multiple requests over the same connection, in which case the connection will have to be remade for every request and cannot be pooled. The Agent will still make the requests to that server, but each one will occur over a new connection.

When a connection is closed by the client or the server, it is removed from the pool. Any unused sockets in the pool will be unrefed so as not to keep the Node.js process running when there are no outstanding requests. (see socket.unref()).

It is good practice, to destroy() an Agent instance when it is no longer in use, because unused sockets consume OS resources.

Sockets are removed from an agent's pool when the socket emits either a 'close' event or an 'agentRemove' event. This means that if you intend to keep one HTTP request open for a long time and don't want it to stay in the pool you can do something along the lines of:

http.get(options, (res) => {
  // 处理事情
}).on('socket', (socket) => {
  socket.emit('agentRemove');
});

You may also use an agent for an individual request. By providing {agent: false} as an option to the http.get() or http.request() functions, a one-time use Agent with default options will be used for the client connection.

agent:false:

http.get({
  hostname: 'localhost',
  port: 80,
  path: '/',
  agent: false  // 创建一个新的代理,只用于本次请求
}, (res) => {
  // 对响应进行处理
});

new Agent([options])#

查看英文版 / 参与翻译

  • options <Object> 用于设置代理的配置选项的集合。可以有以下字段:
    • keepAlive <Boolean> 保持 socket 即使没有请求,以便它们可被将来的请求使用而无需重新建立一个 TCP 连接。默认 = false
    • keepAliveMsecs <Integer> 当使用 keepAlive 选项时,指定 TCP Keep-Alive 数据包的 初始延迟。 当 keepAlive 选项为 falseundefined 时忽视该选项。 默认 = 1000
    • maxSockets <Number> 每个主机允许的最大 socket 数。默认= Infinity
    • maxFreeSockets <Number> 在空闲状态下允许打开的最大 socket 数。 仅当 keepAlive 被设为 true 有效。 默认 = 256.

http.request() 使用的默认的 http.globalAgent 会将所有这些值设为各自的默认值。

要配置其中任何一个,必须创建自己的 http.Agent 实例。

const http = require('http');
var keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);

agent.createConnection(options[, callback])#

查看英文版 / 参与翻译

生产一个用于 HTTP 请求的 socket/stream。

默认情况下,该函数类似于 net.createConnection()。 但是,如果期望更大的灵活性,自定义代理可以重写此方法。

socket/stream 可以由以下两个方法提供:从该函数返回 socket/stream,或传入 callback 的 socket/stream。

callback(err, stream) 参数。

agent.destroy()#

查看英文版 / 参与翻译

销毁当前正被代理使用的任何 socket。

通常不需要这么做。 但是,如果使用的是启用 keepAlive 的代理,则当知道它不再被使用时,最好显式地关闭代理。 否则,在服务器终止之前,socket 可能会挂起开放相当长的时间。

agent.freeSockets#

查看英文版 / 参与翻译

keepAlive 被启用时,返回一个对象,包含当前正在等待被代理使用的 socket 数组。 不要修改。

agent.getName(options)#

查看英文版 / 参与翻译

  • options <Object> 一个提供名称生成信息的选项的集合
    • host <String> 请求发送至的服务器的域名或 IP 地址
    • port <Number> 远程服务器的端口
    • localAddress <String> 当发送请求时,要绑定到网络连接的本地接口
  • 返回: <String>

获取请求选项集合的唯一名称,以确定连接是否可以再利用。 对于一个 HTTP 代理,这会返回 host:port:localAddress。 对于一个 HTTPS 代理,名称会包括 CA、证书、密码和其他 HTTPS/TLS-specific 选项,以确定 socket 的可复用性。

agent.maxFreeSockets#

查看英文版 / 参与翻译

默认设为 256。 对于已启用 keepAlive 的代理,它设置了在空闲状态下可打开的 socket 的最大数量。

agent.maxSockets#

查看英文版 / 参与翻译

默认设为无穷大。 决定每个来源中代理可打开多少个并发的 socket。 来源是一个 'host:port''host:port:localAddress' 组合。

agent.requests#

查看英文版 / 参与翻译

一个包含还未被分配到 socket 的请求队列的对象。 不要修改。

agent.sockets#

查看英文版 / 参与翻译

一个包含当前正被代理使用的 socket 数组的对象。 不要修改。

http.ClientRequest 类#

查看英文版 / 参与翻译

该对象在内部被创建,并从 http.request() 返回。 它表示着一个正在处理的请求,其请求头已进入队列。 请求头仍可使用 setHeader(name, value)getHeader(name)removeHeader(name) API 进行修改。 实际的请求头会与第一个数据块或关闭连接时一起被发送。

要获取响应,需添加一个 'response' 监听器到请求对象上。 当响应头被接收时,请求对象会触发 'response''response' 事件被执行时带有一个参数,该参数是一个 http.IncomingMessage 实例。

'response' 事件期间,可以添加监听器到响应对象;比如监听 'data' 事件。

如果没有添加 'response' 句柄,则响应会被完全丢弃。 当然,如果添加了 'response' 事件句柄,则必须消耗响应对象的数据(当有 'readable' 事件时调用 response.read()、或添加一个 'data' 句柄、或调用 .resume() 方法)。 'end' 事件不会被触发,直到数据被消耗完。 同样,在数据读完之前,它会消耗内存,可能会造成 'process out of memory' 错误。

注意:Node.js 不会检查 Content-Length 和已发送的主体的长度是否相等。

请求实现了[可写流]接口。 这是一个包含以下事件的 EventEmitter

'abort' 事件#

查看英文版 / 参与翻译

当请求已被客户端中止时触发。 该事件仅在首次调用 abort() 时触发。

'aborted' 事件#

查看英文版 / 参与翻译

当请求已被服务器中止且网络 socket 已关闭时触发。

'connect' 事件#

查看英文版 / 参与翻译

每当服务器响应一个带有 CONNECT 方法的请求时触发。 如果该事件未被监听,则接收到 CONNECT 方法的客户端会关闭它们的连接。

一对客户端和服务端会展示如何监听 'connect' 事件:

const http = require('http');
const net = require('net');
const url = require('url');

// 创建一个 HTTP 通道代理
var proxy = http.createServer( (req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
proxy.on('connect', (req, cltSocket, head) => {
  // 连接到一个来源服务器
  var srvUrl = url.parse(`http://${req.url}`);
  var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {
    cltSocket.write('HTTP/1.1 200 连接已建立\r\n' +
                    '委托代理: Node.js-代理\r\n' +
                    '\r\n');
    srvSocket.write(head);
    srvSocket.pipe(cltSocket);
    cltSocket.pipe(srvSocket);
  });
});

// 现在代理正在运行
proxy.listen(1337, '127.0.0.1', () => {

  // 发送一个请求到通道代理
  var options = {
    port: 1337,
    hostname: '127.0.0.1',
    method: 'CONNECT',
    path: 'www.google.com:80'
  };

  var req = http.request(options);
  req.end();

  req.on('connect', (res, socket, head) => {
    console.log('got connected!');

    // 发送一个请求到一个 HTTP 通道
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.google.com:80\r\n' +
                 'Connection: close\r\n' +
                 '\r\n');
    socket.on('data', (chunk) => {
      console.log(chunk.toString());
    });
    socket.on('end', () => {
      proxy.close();
    });
  });
});

'continue' 事件#

查看英文版 / 参与翻译

当服务器发送了一个 100 Continue 的 HTTP 响应时触发,通常因为该请求包含 Expect: 100-continue。 这是客户端应发送请求主体的指令。

'response' 事件#

查看英文版 / 参与翻译

当请求的响应被接收时触发。 该事件只触发一次。

'socket' 事件#

查看英文版 / 参与翻译

当 socket 被分配给请求后触发。

'upgrade' 事件#

查看英文版 / 参与翻译

每当服务器响应一个升级请求时触发。 如果该事件未被监听,则接收到升级请求头的客户端会关闭它们的连接。

一对客户端和服务端会展示如何监听 'upgrade' 事件:

const http = require('http');

// 创建一个 HTTP 服务器
var srv = http.createServer( (req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
srv.on('upgrade', (req, socket, head) => {
  socket.write('HTTP/1.1 101 Web Socket 协议握手\r\n' +
               '升级: WebSocket\r\n' +
               '连接: 升级\r\n' +
               '\r\n');

  socket.pipe(socket); // 回声
});

// 现在服务器正在运行
srv.listen(1337, '127.0.0.1', () => {

  // 发送一个请求
  var options = {
    port: 1337,
    hostname: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket'
    }
  };

  var req = http.request(options);
  req.end();

  req.on('upgrade', (res, socket, upgradeHead) => {
    console.log('已升级!');
    socket.end();
    process.exit(0);
  });
});

request.abort()#

查看英文版 / 参与翻译

标记请求为终止。 调用该方法将导致响应中剩余的数据会被丢弃,且 socket 会被销毁。

request.aborted#

查看英文版 / 参与翻译

If a request has been aborted, this value is the time when the request was aborted, in milliseconds since 1 January 1970 00:00:00 UTC.

request.end([data][, encoding][, callback])#

查看英文版 / 参与翻译

完成发送请求。 如果主体的任何部分未被发送,则会刷新它们到流中。 如果请求被分块,则会发送终止 '0\r\n\r\n'

如果指定了 data,则等同于调用 request.end(callback) 之后调用 response.write(data, encoding)

如果指定了 callback,则当请求流结束时会被调用。

request.flushHeaders()#

查看英文版 / 参与翻译

刷新请求头。

出于效率的考虑,Node.js 通常缓存请求头直到调用 request.end() 或写入请求数据的第一块。 然后试图将请求头和数据打包成单一的 TCP 数据包。

通常那是你想要的(它节省了 TCP 往返),除了当第一个数据块直到很久之后才被发送。 request.flushHeaders() 让你绕过最优化并提前开始请求。

request.setNoDelay([noDelay])#

查看英文版 / 参与翻译

一旦 socket 被分配给请求且已连接,socket.setNoDelay() 会被调用。

request.setSocketKeepAlive([enable][, initialDelay])#

查看英文版 / 参与翻译

一旦 socket 被分配给请求且已连接,socket.setKeepAlive() 会被调用。

request.setTimeout(timeout[, callback])#

查看英文版 / 参与翻译

  • timeout <Number> 一个请求被认为是超时的毫秒数。
  • callback <Function> 可选的函数,当发生超时时调用。与绑定到 timeout 事件的相同。

一旦 socket 被分配给请求且已连接,socket.setTimeout() 会被调用。

返回 request

request.write(chunk[, encoding][, callback])#

查看英文版 / 参与翻译

发送主体的一个数据块。 通过多次调用该方法,用户可以以流的形式将请求主体发送到一个服务器,在这种情况下,当创建请求时,建议使用 ['Transfer-Encoding', 'chunked'] 头行。

encoding 参数是可选的,且仅当 chunk 是一个字符串时有效。默认为 'utf8'

callback 参数是可选的,且当数据块被刷新时调用。

返回 request

http.Server 类#

查看英文版 / 参与翻译

该类继承自 net.Server,且具有以下额外的事件:

'checkContinue' 事件#

查看英文版 / 参与翻译

每当接收到一个带有 HTTP Expect: 100-continue 的请求时触发。 如果该事件未被监听,则服务器会自动响应 100 Continue

处理该事件时,如果客户端应该继续发送请求主体,则调 response.writeContinue(),否则生成一个适当的 HTTP 响应(例如 400 错误请求)。

注意,当该事件被触发且处理后,'request' 事件不会被触发。

'checkExpectation' 事件#

查看英文版 / 参与翻译

每当接收到一个带有 HTTP Expect 请求头的请求时触发,其中值不是 100-continue。 如果该事件未被监听,则服务器会自动响应 417 Expectation Failed

注意,当该事件被触发且处理后,'request' 事件不会被触发。

'clientError' 事件#

查看英文版 / 参与翻译

如果一个客户端触发了一个 'error' 事件,则它会被传递到这里。 该事件的监听器会负责关闭/销毁底层的 socket。 例如,可能希望更温和地用一个 HTTP '400 Bad Request' 响应关闭 socket,而不是突然地切断连接。

默认行为是请求异常是立即销毁 socket。

socket 是发生错误的 net.Socket 对象。

const http = require('http');

const server = http.createServer((req, res) => {
  res.end();
});
server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);

'clientError' 事件发生是,不会有 requestresponse 对象,所以发送的任何 HTTP 响应,包括响应头和内容,必须被直接写入到 socket 对象。 必须小心确保响应是一个被正确格式化的 HTTP 响应消息。

'close' 事件#

查看英文版 / 参与翻译

当服务器关闭时触发。

'connect' 事件#

查看英文版 / 参与翻译

每当一个客户端请求一个 HTTP CONNECT 方法时触发。 如果该事件未被监听,则发送 CONNECT 方法的客户端会关闭它们的连接。

当该事件被触发后,请求的 socket 不会有 'data' 事件监听器,也就是说需要绑定它以用来处理 socket 上被发送到服务器的数据。

'connection' 事件#

查看英文版 / 参与翻译

当一个新的 TCP 流被建立时触发。 socketnet.Socket 类型的一个对象。 通常用户无需访问此事件。 注意,因为协议解析器绑定到 socket 上,socket 不会触发 'readable' 事件。 socket 也可以通过 request.connection 访问。

'request' 事件#

查看英文版 / 参与翻译

每次接收到一个请求时触发。 注意,每个连接可能有多个请求(在 HTTP keep-alive 连接的情况下)。

'upgrade' 事件#

查看英文版 / 参与翻译

每当一个客户端请求一个 HTTP 升级时触发。 如果该事件未被监听,则发送升级的客户端会关闭它们的连接。

当该事件被触发后,请求的 socket 不会有 'data' 事件监听器,也就是说需要绑定它以用来处理 socket 上被发送到服务器的数据。

server.close([callback])#

查看英文版 / 参与翻译

停止服务端接收新的连接。详见 net.Server.close()

server.listen(handle[, callback])#

查看英文版 / 参与翻译

handle 对象可以被设为一个服务器或 socket (任何以下划线开头的 _handle 成员)、或一个 {fd: <n>} 对象。

这会使服务器以指定的句柄接受连接,但假定文件描述符或句柄已经被绑定到了端口或者域 socket。

Windows 平台上不支持监听文件描述符。

该函数是异步的。 callback 会被添加到 'listening' 事件的监听器中。详见 net.Server.listen()

返回 server

注意,server.listen() 方法可能被多次调用。 每次调用都会使用提供的选项重新打开服务器。

server.listen(path[, callback])#

查看英文版 / 参与翻译

启动一个 UNIX socket 服务器,并在给定的 path 上监听连接。

该函数是异步的。 callback 会被添加到 'listening' 事件的监听器中。详见 net.Server.listen(path)

注意,server.listen() 方法可能被多次调用。 每次调用都会使用提供的选项重新打开服务器。

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

查看英文版 / 参与翻译

开始在指定的 porthostname 上接受连接。 如果省略了 hostname,则当 IPv6 可用时,服务器会接受任何 IPv6 地址(::)的连接,否则接受任何 IPv4 地址(0.0.0.0)的连接。 省略 port 参数或使用端口值 0,则操作系统会分配一个随机的端口,该端口可在 'listening' 事件已被触发后通过使用 server.address().port 获取。

要监听一个 UNIX socket,需要提供文件名而不是端口和主机名。

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

该函数是异步的。 callback 会被添加到 'listening' 事件的监听器中。详见 net.Server.listen(port)

注意,server.listen() 方法可能被多次调用。 每次调用都会使用提供的选项重新打开服务器。

server.listening#

查看英文版 / 参与翻译

一个表明服务器是否正在监听连接的布尔值。

server.maxHeadersCount#

查看英文版 / 参与翻译

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

server.setTimeout(msecs, callback)#

查看英文版 / 参与翻译

为 socket 设置超时值。 如果一个超时发生,则 Server 对象上会触发一个 'timeout' 事件,并传入该 socket 作为一个参数。

如果 Server 对象上有 'timeout' 事件监听器,则它会被调用,并带上超时的 socket 作为一个参数。

默认情况下,服务器的超时时间是 2 分钟,且超时后的 socket 会被自动销毁。 但是,如果你为服务器的 'timeout' 事件分配了一个回调函数,则你需要负责处理 socket 的超时。

返回 server

server.timeout#

查看英文版 / 参与翻译

一个 socket 被认定为已超时的空闲毫秒数。

注意,socket 的超时逻辑是在连接上设定的,所以更改这个值只影响服务器新建的连接,而不会影响任何已存在的连接。

设为 0 可禁用请求连接的一切自动超时行为。

http.ServerResponse 类#

查看英文版 / 参与翻译

该对象是由一个 HTTP 服务器(而不是用户)内部创建的。 它作为第二个参数被传入 'request' 事件。

该响应实现(而不是继承自)[可写流]接口。 这是一个有以下事件的 EventEmitter

'close' 事件#

查看英文版 / 参与翻译

表明在 response.end() 被调用或能够刷新之前,底层连接被终止了。

'finish' 事件#

查看英文版 / 参与翻译

当响应已被发送时触发。 更具体地说,当响应头和主体的最后一部分已被交给操作系统通过网络进行传输时,触发该事件。 这并不意味着客户端已接收到任何东西。

该事件触发后,响应对象上不再触发其他事件。

response.addTrailers(headers)#

查看英文版 / 参与翻译

该方法会给响应添加 HTTP 追踪请求头(一个在消息尾部的请求头)。

追踪当响应使用分块编码时才会被发送;如果不是(比如请求是 HTTP/1.0),则它们将被丢弃。

注意,如果想要发送追踪,则 HTTP 要求发送 Trailer 请求头,且在值里带上请求头字段的列表。 例如:

response.writeHead(200, { 'Content-Type': 'text/plain',
                          'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});
response.end();

试图设置一个包含无效字符的请求头字段名称或值会导致抛出一个 TypeError

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

查看英文版 / 参与翻译

该方法告诉服务器所有响应头和主体都已被发送;服务器应将消息视为已完成。 对于每个响应,response.end() 方法必须被调用。

如果指定了 data,则它等同于调用 response.write(data, encoding) 之后调用 response.end(callback)

如果指定了 callback,则当响应流结束时被调用。

response.finished#

查看英文版 / 参与翻译

布尔值,表明响应是否已完成。 开始时为 false。 执行 response.end() 后,该值会变为 true

response.getHeader(name)#

查看英文版 / 参与翻译

读出已经排队但尚未发送到客户端的消息头。 注意,名称不区分大小写。

例子:

var contentType = response.getHeader('content-type');

response.headersSent#

查看英文版 / 参与翻译

布尔值(只读)。 如果消息头已被发送则为 true,否则为 false

response.removeHeader(name)#

查看英文版 / 参与翻译

从隐式发送的队列中移除一个消息头。

例子:

response.removeHeader('Content-Encoding');

response.sendDate#

查看英文版 / 参与翻译

当为 true 时,如果消息头里还不存在日期消息头,则它会被自动生成并在响应中发送。默认为 true

这应该只在测试中才被禁用;HTTP 需要响应日期消息头。

response.setHeader(name, value)#

查看英文版 / 参与翻译

为隐式消息头集合设置一个的消息头值。 如果该消息头已经存在将要发送的消息头集合中,则该值会被覆盖。 如果需要发送多个名称相同的消息头,则使用一个字符串数组。

例子:

response.setHeader('Content-Type', 'text/html');

response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);

试图设置一个包含无效字符的消息头字段名称或值会导致抛出一个 TypeError

当消息头已使用 response.setHeader() 设置,它们会被与其他消息头合并传给 response.writeHead(),带消息头的 response.writeHead() 有更高优先级。

// 返回 content-type = text/plain
const server = http.createServer((req,res) => {
  res.setHeader('Content-Type', 'text/html');
  res.setHeader('X-Foo', 'bar');
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('ok');
});

response.setTimeout(msecs, callback)#

查看英文版 / 参与翻译

设置 socket 的超时时间为 msecs。 如果提供了回调函数,则它会被作为监听器添加到响应对象的 'timeout' 事件。

如果没有 'timeout' 监听器被添加到请求、响应或服务器,则 socket 会在超时后被销毁。 如果在请求、响应或服务器的 'timeout' 事件上分配了句柄,则需要负责处理超时的 socket。

返回 response

response.statusCode#

查看英文版 / 参与翻译

当使用隐式的消息头时(没有显式地调用 response.writeHead()),在消息头被刷新时该属性会控制将被发送到客户端的状态码。

例子:

response.statusCode = 404;

响应头被发送到客户端后,该属性表明被发出的状态码。

response.statusMessage#

查看英文版 / 参与翻译

当使用隐式的消息头时(没有显式地调用 response.writeHead()),在消息头被刷新时该属性会控制将被发送到客户端的状态信息。 如果该值为 undefined,则使用状态码的标准信息。

例子:

response.statusMessage = 'Not found';

响应头被发送到客户端后,该属性表明被发出的状态信息。

response.write(chunk[, encoding][, callback])#

查看英文版 / 参与翻译

如果该方法被调用且 response.writeHead() 还未被调用,则它会切换到隐式消息头模式并刷新隐式消息头。

它会发送一块响应主体。 该方法可被多次调用,以便提供主体连续的部分。

chunk 可以是一个字符串或一个 buffer。 如果 chunk 是一个字符串,则第二个参数指定如何将它编码成一个字节流。 encoding 默认为 'utf8'。 当数据块被刷新时,callback 会被调用。

注意:这是原始的 HTTP 主体,且与可能使用的更高级别的多部分主体编码无关。

response.write() 首次被调用时,它会发送缓冲的头信息和第一块主体到客户端。 response.write() 第二次被调用时,Node.js 会假定你要流化数据,并将它们分别发送。 响应会被缓冲到主体的第一个数据块。

如果整个数据被成功刷新到内核缓冲区,则返回 true。 如果全部或部分数据在用户内存中排队,则返回 false。 当缓冲区再次空闲时,则触发 'drain' 事件。

response.writeContinue()#

查看英文版 / 参与翻译

发送一个 HTTP/1.1 100 Continue 消息到客户端,表明请求主体应该被发送。详见 Server'checkContinue' 事件。

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

查看英文版 / 参与翻译

发送一个响应头给请求。 状态码是一个 3 个数字的 HTTP 状态代码,如 404。 最后一个参数 headers 是响应头。 第二个参数 statusMessage 是可选的。

例子:

var body = 'hello world';
response.writeHead(200, {
  'Content-Length': Buffer.byteLength(body),
  'Content-Type': 'text/plain' });

该方法在消息中只能被调用一次,且必须在 response.end() 被调用之前调用。

如果在调用该方法之前调用 response.write()response.end(),则隐式或可变的消息头会被计算并调用该函数。

当消息头已使用 response.setHeader() 设置,它们会被与其他消息头合并传给 response.writeHead(),带消息头的 response.writeHead() 有更高优先级。

// 返回 content-type = text/plain
const server = http.createServer((req,res) => {
  res.setHeader('Content-Type', 'text/html');
  res.setHeader('X-Foo', 'bar');
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('ok');
});

注意,Content-Length 是以字节(而不是字符)为单位给出的。 以上的例子有效是因为字符串 'hello world' 仅包含单字节字符。 如果主体包含更高编码的字符,则 Buffer.byteLength() 应被用来确定在给定编码中的字节数。 Node.js 不会检查 Content-Length 与已发送的主体长度是否相同。

试图设置一个包含无效字符的消息头字段名称或值会导致抛出一个 TypeError

http.IncomingMessage 类#

查看英文版 / 参与翻译

IncomingMessage 对象由 http.Serverhttp.ClientRequest 创建,并作为第一个参数分别递给 'request''response' 事件。 它可以用来访问响应状态、消息头、以及数据。

它实现了[可读流]接口,还有以下额外的事件、方法、以及属性。

'aborted' 事件#

查看英文版 / 参与翻译

当请求已被客户端中止且网络 socket 已关闭时触发。

'close' 事件#

查看英文版 / 参与翻译

表明底层连接被关闭。 就像 'end',该事件每次响应只发生一次。

message.destroy([error])#

查看英文版 / 参与翻译

调用接收 IncomingMessage 的 socket 的 destroy()。 如果提供了 error,则触发 'error' 事件,且把 error 作为一个参数传入事件的任何监听器。

message.headers#

查看英文版 / 参与翻译

请求/响应头的对象。

报头名称和值的键值对。 报头名称为小写。 例如:

// 输出类似以下的东西:
//
// { 'user-agent': 'curl/7.22.0',
//   host: '127.0.0.1:8000',
//   accept: '*/*' }
console.log(request.headers);

原始报头中的重复数据会按以下方式根据报头名称进行处理:

  • 重复的 ageauthorizationcontent-lengthcontent-typeetagexpiresfromhostif-modified-sinceif-unmodified-sincelast-modifiedlocationmax-forwardsproxy-authorizationrefererretry-after 、或 user-agent 会被丢弃。
  • set-cookie 始终是一个数组。重复的会被添加到数组。
  • 对于所有的其他报头,其值使用 ', ' 连接。

message.httpVersion#

查看英文版 / 参与翻译

当服务器请求时,HTTP 版本由客户端发送。 当客户端响应时,HTTP 版本由所连接的服务器发送。 可能的值有 '1.1''1.0'

message.httpVersionMajor 是第一个整数,message.httpVersionMinor 是第二个整数。

message.method#

查看英文版 / 参与翻译

仅适用于从 http.Server 获得的请求。

请求方法是一个字符串。 只读。 例如:'GET''DELETE'

message.rawHeaders#

查看英文版 / 参与翻译

接收到的原始请求/响应头列表。

注意,键和值是在同一列表中。 它不是一个元组列表。 所以,偶数偏移量为键,奇数偏移量为对应的值。

报头名称没有转换为小写,也没有合并去重。

// 输出类似以下的东西:
//
// [ 'user-agent',
//   'this is invalid because there can be only one',
//   'User-Agent',
//   'curl/7.22.0',
//   'Host',
//   '127.0.0.1:8000',
//   'ACCEPT',
//   '*/*' ]
console.log(request.rawHeaders);

message.rawTrailers#

查看英文版 / 参与翻译

接收到的原始的请求/响应报尾的键和值。 只在 'end' 事件时填入。

message.setTimeout(msecs, callback)#

查看英文版 / 参与翻译

调用 message.connection.setTimeout(msecs, callback)

返回 message

message.statusCode#

查看英文版 / 参与翻译

仅适用于从 http.ClientRequest 获得的响应。

3 位数字的 HTTP 响应状态码。 如 404

message.statusMessage#

查看英文版 / 参与翻译

仅适用于从 http.ClientRequest 获得的响应。

HTTP 响应状态消息(原因描述)。如 OKInternal Server Error

message.socket#

查看英文版 / 参与翻译

与连接有关的 net.Socket 对象。

通过 HTTPS 的支持,使用 request.socket.getPeerCertificate() 获取客户端的认证信息。

message.trailers#

查看英文版 / 参与翻译

请求/响应报尾对象。 只在 'end' 事件时填入。

message.url#

查看英文版 / 参与翻译

仅适用于从 http.Server 获得的请求。

请求的 URL 字符串。 仅包含 HTTP 请求实际存在的 URL。 如果请求是:

GET /status?name=ryan HTTP/1.1\r\n
Accept: text/plain\r\n
\r\n

request.url 会是:

'/status?name=ryan'

如果想将 URL 解析成各个部分,可以使用 require('url').parse(request.url)。 例子:

$ node
> require('url').parse('/status?name=ryan')
{
  href: '/status?name=ryan',
  search: '?name=ryan',
  query: 'name=ryan',
  pathname: '/status'
}

如果想从查询字符串中提取参数,可以使用 require('querystring').parse 函数,或传入 true 作为 require('url').parse 的第二个参数。 例子:

$ node
> require('url').parse('/status?name=ryan', true)
{
  href: '/status?name=ryan',
  search: '?name=ryan',
  query: {name: 'ryan'},
  pathname: '/status'
}

http.METHODS#

查看英文版 / 参与翻译

解析器支持的 HTTP 方法列表。

http.STATUS_CODES#

查看英文版 / 参与翻译

所有的标准 HTTP 响应状态码的集合,以及各自的简短描述。 例如,http.STATUS_CODES[404] === 'Not Found'

http.createClient([port][, host])#

查看英文版 / 参与翻译

稳定性: 0 - 废弃的: 使用 http.request() 代替。

Constructs a new HTTP client. port and host refer to the server to be connected to.

http.createServer([requestListener])#

查看英文版 / 参与翻译

返回一个新建的 http.Server 实例。

requestListener 是一个会被自动添加到 'request' 事件中的函数。

http.get(options[, callback])#

查看英文版 / 参与翻译

因为大多数请求都是 GET 请求且不带主体,所以 Node.js 提供了这个便捷的方法。 该方法与 http.request() 唯一的区别是它设置请求方法为 GET 且自动调用 req.end()。 注意,响应数据必须在回调中被消耗,原因详见 http.ClientRequest 章节。

callback 被调用时只有一个参数,它是 http.IncomingMessage 的一个实例。

一个获取 JSON 的例子:

http.get('http://nodejs.org/dist/index.json', (res) => {
  const statusCode = res.statusCode;
  const contentType = res.headers['content-type'];

  let error;
  if (statusCode !== 200) {
    error = new Error(`请求失败。\n` +
                      `状态码: ${statusCode}`);
  } else if (!/^application\/json/.test(contentType)) {
    error = new Error(`无效的 content-type.\n` +
                      `期望 application/json 但获取的是 ${contentType}`);
  }
  if (error) {
    console.log(error.message);
    // 消耗响应数据以释放内存
    res.resume();
    return;
  }

  res.setEncoding('utf8');
  let rawData = '';
  res.on('data', (chunk) => rawData += chunk);
  res.on('end', () => {
    try {
      let parsedData = JSON.parse(rawData);
      console.log(parsedData);
    } catch (e) {
      console.log(e.message);
    }
  });
}).on('error', (e) => {
  console.log(`错误: ${e.message}`);
});

http.globalAgent#

查看英文版 / 参与翻译

Agent 的全局实例,作为所有 HTTP 客户端请求的默认 Agent

http.request(options[, callback])#

查看英文版 / 参与翻译

  • options <Object>
    • protocol <String> 使用的协议。默认为 'http:'
    • host <String> 请求发送至的服务器的域名或 IP 地址。默认为 'localhost'
    • hostname <String> host 的别名。为了支持 url.parse()hostname 优于 host
    • family <Number> 当解析 hosthostname 时使用的 IP 地址族。 有效值是 46。当未指定时,则同时使用 IP v4 和 v6。
    • port <Number> 远程服务器的端口。默认为 80
    • localAddress <String> 要绑定到网络连接的本地接口。
    • socketPath <String> Unix 域 Socket(使用 host:port 或 socketPath 的其中之一)。
    • method <String> 一个指定 HTTP 请求方法的字符串。默认为 'GET'
    • path <String> 请求的路径。默认为 '/'。 应包括查询字符串(如有的话)。如 '/index.html?page=12'。 当请求的路径中包含非法字符时,会抛出异常。 目前只有空字符会被拒绝,但未来可能会变化。
    • headers <Object> 一个包含请求头的对象。
    • auth <String> 基本身份验证,如 'user:password' 来计算 Authorization 头。
    • agent <http.Agent> | <Boolean> 控制 Agent 的行为。 可能的值有:
      • undefined (默认): 对该主机和端口使用 http.globalAgent
      • Agent 对象:显式地使用传入的 Agent
      • false: 产生一个新的使用默认值的 Agent
    • createConnection <Function> 当不使用 agent 选项时,产生一个用于请求的 socket/stream 的函数。 这可以用于避免创建一个自定义的 Agent 类,只是为了覆盖默认的 createConnection 函数。详见 agent.createConnection()
    • timeout <Integer>: 一个数值,指定 socket 超时的毫秒数。 它会在 socket 被连接时设置超时。
  • callback <Function>
  • 返回: <http.ClientRequest>

Node.js 维护每台服务器的多个连接来进行 HTTP 请求。 该函数允许显式地发出请求。

options 可以是一个对象或一个字符串。 如果 options 是一个字符串,它会被自动使用 url.parse() 解析。

可选的 callback 参数会被添加为 'response' 事件的单次监听器。

http.request() 返回一个 http.ClientRequest 类的实例。 ClientRequest 实例是一个可写流。 如果需要通过 POST 请求上传一个文件,则写入到 ClientRequest 对象。

例子:

var postData = querystring.stringify({
  'msg' : 'Hello World!'
});

var options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': Buffer.byteLength(postData)
  }
};

var req = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(`主体: ${chunk}`);
  });
  res.on('end', () => {
    console.log('响应中已无数据。');
  });
});

req.on('error', (e) => {
  console.log(`请求遇到问题: ${e.message}`);
});

// 写入数据到请求主体
req.write(postData);
req.end();

注意,在例子中调用了 req.end()。 使用 http.request() 必须总是调用 req.end() 来表明请求已经结束,即使没有数据被写入请求主体。

如果请求过程中遇到任何错误(DNS 解析错误、TCP 级的错误、或实际的 HTTP 解析错误),则在返回的请求对象中会触发 'error' 事件。 对于所有的 'error' 事件,如果没有注册监听器,则抛出错误。

以下是需要注意的几个特殊的请求头。

  • 发送一个 'Connection: keep-alive' 会通知 Node.js,服务器的连接应一直持续到下一个请求。

  • 发送一个 'Content-Length' 请求头会禁用默认的块编码。

  • 发送一个 'Expect' 请求头会立即发送请求头。 通常情况下,当发送 'Expect: 100-continue' 时,应该设置一个超时并监听 'continue' 事件。 详见 RFC2616 章节 8.2.3。

  • 发送一个 Authorization 请求头会覆盖使用 auth 选项计算基本身份验证。