目录

http(HTTP)#

稳定性: 2 - 稳定

源代码: lib/http.js

若要使用 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 类#

Agent 负责管理 HTTP 客户端的连接持久性和重用。 它为给定的主机和端口维护一个待处理请求队列,为每个请求重用单独的套接字连接,直到队列为空,此时套接字被销毁或放入连接池,以便再次用于请求到同一个主机和端口。 销毁还是放入连接池取决于 keepAlive 选项

连接池中的连接已启用 TCP Keep-Alive,但服务器仍可能关闭空闲连接,在这种情况下,它们将从连接池中删除,并且当为该主机和端口发出新的 HTTP 请求时将建立新连接。 服务器也可以拒绝通过同一连接允许多个请求,在这种情况下,必须为每个请求重新建立连接,并且不能放入连接池。 Agent 仍将向该服务器发出请求,但每个请求都将通过新连接发生。

当客户端或服务器关闭连接时,它将从连接池中删除。 连接池中任何未使用的套接字都将被销毁,以便当没有未完成的请求时不用保持 Node.js 进程运行。 (参见 socket.unref())。

当不再使用时最好 destroy() Agent 实例,因为未使用的套接字会消耗操作系统资源。

当套接字触发 'close' 事件或 'agentRemove' 事件时,则套接字将从代理中删除。 当打算长时间保持一个 HTTP 请求打开而不将其保留在代理中时,可以执行以下操作:

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

代理也可以用于单个请求。 通过提供 {agent: false} 作为 http.get()http.request() 函数的选项,则将使用一次性的具有默认选项的 Agent 用于客户端连接。

agent:false 的示例:

http.get({
  hostname: 'localhost',
  port: 80,
  path: '/',
  agent: false  // 仅为此一个请求创建一个新代理。
}, (res) => {
  // 用响应做些事情。
});

new Agent([options])#

  • options <Object> 要在代理上设置的可配置选项集。可以包含以下字段:
    • keepAlive <boolean> 即使没有未完成的请求,也要保持套接字,这样它们就可以被用于将来的请求而无需重新建立 TCP 连接。 不要与 Connection 请求头的 keep-alive 值混淆。 Connection: keep-alive 请求头始终在使用代理时发送,除非明确指定 Connection 请求头、或者 keepAlivemaxSockets 选项分别设置为 falseInfinity,在这种情况下将会使用 Connection: close默认值: false
    • keepAliveMsecs <number> 当使用 keepAlive 选项时,指定用于 TCP Keep-Alive 数据包的初始延迟。当 keepAlive 选项为 falseundefined 时则忽略。默认值: 1000
    • maxSockets <number> 每个主机允许的套接字的最大数量。默认值: Infinity
    • maxTotalSockets <number> Maximum number of sockets allowed for all hosts in total. Each request will use a new socket until the maximum is reached. Default: Infinity.
    • maxFreeSockets <number> 在空闲状态下保持打开的套接字的最大数量。仅当 keepAlive 被设置为 true 时才相关。默认值: 256
    • scheduling <string> Scheduling strategy to apply when picking the next free socket to use. It can be 'fifo' or 'lifo'. The main difference between the two scheduling strategies is that 'lifo' selects the most recently used socket, while 'fifo' selects the least recently used socket. In case of a low rate of request per second, the 'lifo' scheduling will lower the risk of picking a socket that might have been closed by the server due to inactivity. In case of a high rate of request per second, the 'fifo' scheduling will maximize the number of open sockets, while the 'lifo' scheduling will keep it as low as possible. Default: 'fifo'.
    • timeout <number> 套接字的超时时间,以毫秒为单位。这会在套接字被连接之后设置超时时间。

socket.connect() 中的 options 也受支持。

http.request() 使用的默认的 http.globalAgent 具有所有这些值且被设置为各自的默认值。

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

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

agent.createConnection(options[, callback])#

生成用于 HTTP 请求的套接字或流。

默认情况下,此函数与 net.createConnection() 相同。 但是,如果需要更大的灵活性,自定义代理可能会覆盖此方法。

可以通过以下两种方式之一提供套接字或流:通过从此函数返回套接字或流,或者通过将套接字或流传给 callback

此方法保证返回 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

callback 的参数是 (err, stream)

agent.keepSocketAlive(socket)#

socket 与请求分离并且可以由 Agent 保留时调用。 默认行为是:

socket.setKeepAlive(true, this.keepAliveMsecs);
socket.unref();
return true;

此方法可以由特定的 Agent 子类重写。 如果此方法返回一个假值,则将销毁套接字而不是将其保留以用于下一个请求。

socket 参数可以是 <net.Socket><stream.Duplex> 的子类)的实例。

agent.reuseSocket(socket, request)#

由于 keep-alive 选项而在持久化后将 socket 附加到 request 时调用。 默认行为是:

socket.ref();

此方法可以由特定的 Agent 子类重写。

socket 参数可以是 <net.Socket><stream.Duplex> 的子类)的实例。

agent.destroy()#

销毁代理当前使用的所有套接字。

通常没有必要这样做。 但是,如果使用启用了 keepAlive 的代理,则最好在代理不再使用时显式关闭代理。 否则,在服务器终止套接字之前,套接字可能会挂起很长时间。

agent.freeSockets#

一个对象,其中包含当启用 keepAlive 时代理正在等待使用的套接字数组。 不要修改。

freeSockets 列表中的 socket 会在 `'timeout' 时自动被销毁并从数组中删除。

agent.getName(options)#

  • options <Object> 一组选项,为生成名称提供信息。
    • host <string> 请求发送至的服务器的域名或 IP 地址。
    • port <number> 远程服务器的端口。
    • localAddress <string> 为网络连接绑定的本地接口。
    • family <integer> 如果不等于 undefined,则必须为 4 或 6。
  • 返回: <string>

获取一组请求选项的唯一名称,以判定一个连接是否可以被重用。 对于 HTTP 代理,这返回 host:port:localAddresshost:port:localAddress:family。 对于 HTTPS 代理,该名称包括 CA、证书、密码、以及其他可判定套接字可重用性的 HTTPS/TLS 特有的选项。

agent.maxFreeSockets#

默认设置为 256。 对于启用了 keepAlive 的代理,这将设置在空闲状态下保持打开的最大套接字数。

agent.maxSockets#

默认情况下设置为 Infinity。 决定代理可以为每个来源打开多少并发套接字。 来源是 agent.getName() 的返回值。

agent.maxTotalSockets#

By default set to Infinity. Determines how many concurrent sockets the agent can have open. Unlike maxSockets, this parameter applies across all origins.

agent.requests#

一个对象,包含尚未分配给套接字的请求队列。 不要修改。

agent.sockets#

一个对象,包含当前代理正在使用的套接字数组。 不要修改。

http.ClientRequest 类#

此对象由 http.request() 内部创建并返回。 它表示正在进行中的请求(请求头已进入队列)。 请求头仍然可以使用 setHeader(name, value)getHeader(name)removeHeader(name) API 进行改变。 实际的请求头会与第一个数据块一起发送,或者当调用 request.end() 时发送。

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

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

如果没有添加 'response' 事件处理函数,则响应会被完全地丢弃。 但是,如果添加了 'response' 事件处理函数,则响应对象中的数据必须被消费(每当有 'readable' 事件时调用 response.read()、或添加 'data' 事件处理函数、或调用 .resume() 方法)。 在数据被消费完之前,不会触发 'end' 事件。 此外,在读取数据之前,它会占用内存,这可能最终会导致进程内存不足的错误。

request 对象不同,如果响应过早地关闭,则 response 对象不会触发 'error' 事件而是触发 'aborted' 事件。

Node.js 不会检查 Content-Length 与已传输的请求体的长度是否相等。

'abort' 事件#

当请求被客户端中止时触发。 此事件仅在第一次调用 abort() 时触发。

'connect' 事件#

每次服务器使用 CONNECT 方法响应请求时都会触发。 如果未监听此事件,则接收 CONNECT 方法的客户端将关闭其连接。

此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

客户端和服务器对演示了如何监听 'connect' 事件:

const http = require('http');
const net = require('net');
const { URL } = require('url');

// 创建 HTTP 隧道代理。
const proxy = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('响应内容');
});
proxy.on('connect', (req, clientSocket, head) => {
  // 连接到原始服务器。
  const { port, hostname } = new URL(`http://${req.url}`);
  const serverSocket = net.connect(port || 80, hostname, () => {
    clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node.js-Proxy\r\n' +
                    '\r\n');
    serverSocket.write(head);
    serverSocket.pipe(clientSocket);
    clientSocket.pipe(serverSocket);
  });
});

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

  // 向隧道代理发出请求。
  const options = {
    port: 1337,
    host: '127.0.0.1',
    method: 'CONNECT',
    path: 'apiref.com:80'
  };

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

  req.on('connect', (res, socket, head) => {
    console.log('已连接');

    // 通过 HTTP 隧道发出请求。
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: apiref.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。 这是客户端应发送请求主体的指令。

'information' 事件#

服务器发送 1xx 中间响应(不包括 101 Upgrade)时触发。 此事件的监听器将会接收一个对象,该对象包含 HTTP 版本,状态码,状态消息,键值对请求头对象、以及具有原始请求头名称和值的数组。

const http = require('http');

const options = {
  host: '127.0.0.1',
  port: 8080,
  path: '/length_request'
};

// 发出请求。
const req = http.request(options);
req.end();

req.on('information', (info) => {
  console.log(`获得主响应之前的信息: ${info.statusCode}`);
});

101 Upgrade 状态不会触发此事件,因为它们与传统的 HTTP 请求/响应链断开,例如 Web 套接字、现场 TLS 升级、或 HTTP 2.0。 要收到 101 Upgrade 的通知,请改为监听 'upgrade' 事件。

'response' 事件#

当收到此请求的响应时触发。 此事件仅触发一次。

'socket' 事件#

此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

'timeout' 事件#

当底层套接字因不活动而超时时触发。 这只会通知套接字已空闲。 必须手动中止请求。

另请参见:request.setTimeout()

'upgrade' 事件#

每次服务器响应升级请求时发出。 如果未监听此事件且响应状态码为 101 Switching Protocols,则接收升级响应头的客户端将关闭其连接。

此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

客户端服务器对,演示如何监听 'upgrade' 事件。

const http = require('http');

// 创建 HTTP 服务器。
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('响应内容');
});
server.on('upgrade', (req, socket, head) => {
  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n');

  socket.pipe(socket); // 响应回去。
});

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

  // 发送请求。
  const options = {
    port: 1337,
    host: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket'
    }
  };

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

  req.on('upgrade', (res, socket, upgradeHead) => {
    console.log('接收到响应');
    socket.end();
    process.exit(0);
  });
});

request.abort()#

稳定性: 0 - 弃用: 改为使用 request.destroy()

将请求标记为中止。 调用此方法将导致响应中剩余的数据被丢弃并且套接字被销毁。

request.aborted#

如果请求已中止,则 request.aborted 属性将会为 true

request.connection#

稳定性: 0 - 弃用. 改为使用 request.socket.

See request.socket.

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

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

如果指定了 data,则相当于调用 request.write(data, encoding) 之后再调用 request.end(callback)

如果指定了 callback,则当请求流完成时将调用它。

request.destroy([error])#

  • error <Error> Optional, an error to emit with 'error' event.
  • Returns: <this>

Destroy the request. Optionally emit an 'error' event, and emit a 'close' event. Calling this will cause remaining data in the response to be dropped and the socket to be destroyed.

See writable.destroy() for further details.

request.destroyed#

Is true after request.destroy() has been called.

See writable.destroyed for further details.

request.finished#

稳定性: 0 - 弃用. 改为使用 request.writableEnded.

The request.finished property will be true if request.end() has been called. request.end() will automatically be called if the request was initiated via http.get().

request.flushHeaders()#

刷新请求头。

出于效率原因,Node.js 通常会缓冲请求头,直到调用 request.end() 或写入第一个请求数据块。 然后,它尝试将请求头和数据打包到单个 TCP 数据包中。

这通常是期望的(它节省了 TCP 往返),但是可能很晚才发送第一个数据。 request.flushHeaders() 绕过优化并启动请求。

request.getHeader(name)#

读取请求中的一个请求头。 该名称不区分大小写。 返回值的类型取决于提供给 request.setHeader() 的参数。

request.setHeader('content-type', 'text/html');
request.setHeader('Content-Length', Buffer.byteLength(body));
request.setHeader('Cookie', ['type=ninja', 'language=javascript']);
const contentType = request.getHeader('Content-Type');
// 'contentType' 是 'text/html'。
const contentLength = request.getHeader('Content-Length');
// 'contentLength' 的类型为数值。
const cookie = request.getHeader('Cookie');
// 'cookie' 的类型为字符串数组。

request.maxHeadersCount#

限制最大响应头数。 如果设置为 0,则不会应用任何限制。

request.path#

request.method#

request.host#

request.protocol#

request.removeHeader(name)#

移除已定义到请求头对象中的请求头。

request.removeHeader('Content-Type');

request.reusedSocket#

  • <boolean> Whether the request is send through a reused socket.

When sending request through a keep-alive enabled agent, the underlying socket might be reused. But if server closes connection at unfortunate time, client may run into a 'ECONNRESET' error.

const http = require('http');

// Server has a 5 seconds keep-alive timeout by default
http
  .createServer((req, res) => {
    res.write('hello\n');
    res.end();
  })
  .listen(3000);

setInterval(() => {
  // Adapting a keep-alive agent
  http.get('http://localhost:3000', { agent }, (res) => {
    res.on('data', (data) => {
      // Do nothing
    });
  });
}, 5000); // Sending request on 5s interval so it's easy to hit idle timeout

By marking a request whether it reused socket or not, we can do automatic error retry base on it.

const http = require('http');
const agent = new http.Agent({ keepAlive: true });

function retriableRequest() {
  const req = http
    .get('http://localhost:3000', { agent }, (res) => {
      // ...
    })
    .on('error', (err) => {
      // Check if retry is needed
      if (req.reusedSocket && err.code === 'ECONNRESET') {
        retriableRequest();
      }
    });
}

retriableRequest();

request.setHeader(name, value)#

为请求头对象设置单个请求头的值。 如果此请求头已存在于待发送的请求头中,则其值将被替换。 这里可以使用字符串数组来发送具有相同名称的多个请求头。 非字符串值将被原样保存。 因此 request.getHeader() 可能会返回非字符串值。 但是非字符串值将转换为字符串以进行网络传输。

request.setHeader('Content-Type', 'application/json');

或:

request.setHeader('Cookie', ['type=ninja', 'language=javascript']);

request.setNoDelay([noDelay])#

一旦将套接字分配给此请求并且连接了套接字,就会调用 socket.setNoDelay()

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

一旦将套接字分配给此请求并连接了套接字,就会调用 socket.setKeepAlive()

request.setTimeout(timeout[, callback])#

一旦将套接字分配给此请求并且连接了套接字,就会调用 socket.setTimeout()

request.socket#

指向底层套接字。 通常用户无需访问此属性。 特别是,由于协议解析器附加到套接字的方式,套接字将不会触发 'readable' 事件。

const http = require('http');
const options = {
  host: 'apiref.com',
};
const req = http.get(options);
req.end();
req.once('response', (res) => {
  const ip = req.socket.localAddress;
  const port = req.socket.localPort;
  console.log(`您的 IP 地址是 ${ip},源端口是 ${port}`);
  // 使用响应对象。
});

此属性保证是 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

request.writableEnded#

在调用 request.end() 之后为 true。 此属性不表明是否已刷新数据,对于这种应该使用 request.writableFinished

request.writableFinished#

如果在触发 'finish' 事件之前,所有数据都已刷新到底层系统,则为 true

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

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

encoding 参数是可选的,仅当 chunk 是字符串时才适用。 默认为 'utf8'

callback 参数是可选的,当刷新此数据块时调用,但仅当数据块非空时才会调用。

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

当使用空字符串或 buffer 调用 write 函数时,则什么也不做且等待更多输入。

http.Server 类#

'checkContinue' 事件#

每次收到 HTTP Expect: 100-continue 的请求时都会触发。 如果未监听此事件,服务器将自动响应 100 Continue

处理此事件时,如果客户端应继续发送请求主体,则调用 response.writeContinue(),如果客户端不应继续发送请求主体,则生成适当的 HTTP 响应(例如 400 Bad Request)。

在触发和处理此事件时,不会触发 'request' 事件。

'checkExpectation' 事件#

每次收到带有 HTTP Expect 请求头的请求时触发,其中值不是 100-continue。 如果未监听此事件,则服务器将根据需要自动响应 417 Expectation Failed

在触发和处理此事件时,不会触发 'request' 事件。

'clientError' 事件#

如果客户端连接触发 'error' 事件,则会在此处转发。 此事件的监听器负责关闭或销毁底层套接字。 例如,用户可能希望使用自定义 HTTP 响应更优雅地关闭套接字,而不是突然切断连接。

此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

默认行为是尝试使用 HTTP 400 Bad Request 关闭套接字、或者在 HPE_HEADER_OVERFLOW 错误的情况下尝试关闭 HTTP 431 Request Header Fields Too Large。 如果套接字不可写或已写入数据,则会被立即销毁。

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 响应消息。

errError 实例,有以下两个额外的部分:

  • bytesParsed: Node.js 可能正确解析的请求包的字节数。
  • rawPacket: 当前请求的原始数据包。

In some cases, the client has already received the response and/or the socket has already been destroyed, like in case of ECONNRESET errors. Before trying to send data to the socket, it is better to check that it is still writable.

server.on('clientError', (err, socket) => {
  if (err.code === 'ECONNRESET' || !socket.writable) {
    return;
  }

  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});

'close' 事件#

当服务器关闭时触发。

'connect' 事件#

每次客户端请求 HTTP CONNECT 方法时触发。 如果未监听此事件,则请求 CONNECT 方法的客户端将关闭其连接。

此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

触发此事件后,请求的套接字将没有 'data' 事件监听器,这意味着它需要绑定才能处理发送到该套接字上的服务器的数据。

'connection' 事件#

建立新的 TCP 流时会触发此事件。 socket 通常是 net.Socket 类型的对象。 通常用户无需访问此事件。 特别是,由于协议解析器附加到套接字的方式,套接字将不会触发 'readable' 事件。 也可以通过 request.socket 访问 socket

用户也可以显式触发此事件,以将连接注入 HTTP 服务器。 在这种情况下,可以传入任何 Duplex 流。

如果在此处调用 socket.setTimeout(),则当套接字已提供请求时(如果 server.keepAliveTimeout 为非零),超时将会被 server.keepAliveTimeout 替换。

此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

'request' 事件#

每当有请求时触发。 每个连接可能有多个请求(对于 HTTP Keep-Alive 连接而言)。

'upgrade' 事件#

每次客户端请求 HTTP 升级时发出。 监听此事件是可选的,客户端无法坚持更改协议。

触发此事件后,请求的套接字将没有 'data' 事件监听器,这意味着它需要绑定才能处理发送到该套接字上的服务器的数据。

此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

server.close([callback])#

停止服务器接受新连接。 请参见 net.Server.close()

server.headersTimeout#

限制解析器等待接收完整 HTTP 请求头的时间。

如果不活动,则适用 server.timeout 中定义的规则。 但是,如果请求头发送速度非常慢(默认情况下,每 2 分钟最多一个字节),那么基于不活动的超时仍然允许连接保持打开状态。 为了防止这种情况,每当请求头数据到达时,进行额外的检查,自建立连接以来,没有超过 server.headersTimeout 毫秒。 如果检查失败,则在服务器对象上触发 'timeout' 事件,并且(默认情况下)套接字被销毁。 有关如何自定义超时行为的详细信息,请参见 server.timeout

server.listen()#

启动 HTTP 服务器用于监听连接。 此方法与 net.Server 中的 server.listen() 相同。

server.listening#

  • <boolean> 表明服务器是否正在监听连接。

server.maxHeadersCount#

限制最大传入请求头数。 如果设置为 0,则不会应用任何限制。

server.requestTimeout#

Sets the timeout value in milliseconds for receiving the entire request from the client.

If the timeout expires, the server responds with status 408 without forwarding the request to the request listener and then closes the connection.

It must be set to a non-zero value (e.g. 120 seconds) to proctect against potential Denial-of-Service attacks in case the server is deployed without a reverse proxy in front.

server.setTimeout([msecs][, callback])#

设置套接字的超时值,并在服务器对象上触发 'timeout' 事件,如果发生超时,则将套接字作为参数传入。

如果服务器对象上有 'timeout' 事件监听器,则将使用超时的套接字作为参数调用它。

默认情况下,服务器不会使 socket 超时。 但是,如果将回调分配给服务器的 'timeout' 事件,则必须显式处理超时。

server.timeout#

  • <number> 超时时间(以毫秒为单位)。默认值: 120000(2 分钟)。

认定套接字超时的不活动毫秒数。

值为 0 将禁用传入连接的超时行为。

套接字超时逻辑在连接时设置,因此更改此值仅影响到服务器的新连接,而不影响任何现有连接。

server.keepAliveTimeout#

  • <number> 超时时间(以毫秒为单位)。默认值: 5000(5 秒)。

服务器在完成写入最后一个响应之后,在销毁套接字之前需要等待其他传入数据的非活动毫秒数。 如果服务器在保持活动超时被触发之前接收到新数据,它将重置常规非活动超时,即 server.timeout

值为 0 将禁用传入连接上的保持活动超时行为。 值为 0 使得 http 服务器的行为与 8.0.0 之前的 Node.js 版本类似,后者没有保持活动超时。

套接字超时逻辑在连接时设置,因此更改此值仅影响到服务器的新连接,而不影响任何现有连接。

http.ServerResponse 类#

此对象由 HTTP 服务器在内部创建,而不是由用户创建。 它会作为第二个参数传给 'request' 事件。

'close' 事件#

表明响应已完成,或者其底层的连接过早被终止(在响应完成之前)。

'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.connection#

稳定性: 0 - 弃用. 改为使用 response.socket.

See response.socket.

response.cork()#

See writable.cork().

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

此方法向服务器发出信号,表明已发送所有响应头和主体,该服务器应该视为此消息已完成。 必须在每个响应上调用此 response.end() 方法。

如果指定了 data,则相当于调用 response.write(data, encoding) 之后再调用 response.end(callback)

如果指定了 callback,则当响应流完成时将调用它。

response.finished#

稳定性: 0 - 弃用. 改为使用 response.writableEnded.

The response.finished property will be true if response.end() has been called.

response.flushHeaders()#

刷新响应头。 另可参见:request.flushHeaders()

response.getHeader(name)#

读出已排队但未发送到客户端的响应头。 该名称不区分大小写。 返回值的类型取决于提供给 response.setHeader() 的参数。

response.setHeader('Content-Type', 'text/html');
response.setHeader('Content-Length', Buffer.byteLength(body));
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
const contentType = response.getHeader('content-type');
// contentType 是 'text/html'。
const contentLength = response.getHeader('Content-Length');
// contentLength 的类型为数值。
const setCookie = response.getHeader('set-cookie');
// setCookie 的类型为字符串数组。

response.getHeaderNames()#

返回一个数组,其中包含当前传出的响应头的唯一名称。 所有响应头名称都是小写的。

response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);

const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie']

response.getHeaders()#

返回当前传出的响应头的浅拷贝。 由于使用浅拷贝,因此可以更改数组的值而无需额外调用各种与响应头相关的 http 模块方法。 返回对象的键是响应头名称,值是各自的响应头值。 所有响应头名称都是小写的。

response.getHeaders() 方法返回的对象不是从 JavaScript Object 原型继承的。 这意味着典型的 Object 方法,如 obj.toString()obj.hasOwnProperty() 等都没有定义并且不起作用。

response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);

const headers = response.getHeaders();
// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] }

response.hasHeader(name)#

如果当前在传出的响应头中设置了由 name 标识的响应头,则返回 true。 响应头名称匹配不区分大小写。

const hasContentType = response.hasHeader('content-type');

response.headersSent#

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

response.removeHeader(name)#

移除排队等待中的隐式发送的响应头。

response.removeHeader('Content-Encoding');

response.sendDate#

如果为 true,则 Date 响应头将自动生成并在响应中发送(如果响应头中尚不存在)。 默认为 true

这应该仅在测试时才禁用,HTTP 响应需要 Date 响应头。

response.setHeader(name, value)#

为隐式响应头设置单个响应头的值。 如果此响应头已存在于待发送的响应头中,则其值将被替换。 在这里可以使用字符串数组来发送具有相同名称的多个响应头。 非字符串值将被原样保存。 因此 response.getHeader() 可能返回非字符串值。 但是非字符串值将转换为字符串以进行网络传输。

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.writeHead() 方法并且尚未调用此方法,则它将直接将提供的响应头值写入网络通道而不在内部进行缓存,并且响应头上的 response.getHeader() 将不会产生预期的结果。 如果需要渐进的响应头填充以及将来可能的检索和修改,则使用 response.setHeader() 而不是 response.writeHead()

response.setTimeout(msecs[, callback])#

将套接字的超时值设置为 msecs。 如果提供了回调,则会将其作为监听器添加到响应对象上的 'timeout' 事件中。

如果没有 'timeout' 监听器添加到请求、响应、或服务器,则套接字在超时时将被销毁。 如果有回调处理函数分配给请求、响应、或服务器的 'timeout' 事件,则必须显式处理超时的套接字。

response.socket#

指向底层的套接字。 通常用户不需要访问此属性。 特别是,由于协议解析器附加到套接字的方式,套接字将不会触发 'readable' 事件。 在调用 response.end() 之后,此属性将为空。

const http = require('http');
const server = http.createServer((req, res) => {
  const ip = res.socket.remoteAddress;
  const port = res.socket.remotePort;
  res.end(`您的 IP 地址是 ${ip},您的源端口是 ${port}`);
}).listen(3000);

此属性保证是 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

response.statusCode#

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

response.statusCode = 404;

响应头发送到客户端后,此属性表示已发送的状态码。

response.statusMessage#

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

response.statusMessage = 'Not found';

响应头发送到客户端后,此属性表示已发送的状态消息。

response.uncork()#

See writable.uncork().

response.writableEnded#

在调用 response.end() 之后为 true。 此属性不表明数据是否已刷新,对于这种应该使用 response.writableFinished

response.writableFinished#

如果在触发 'finish' 事件之前,所有数据都已刷新到底层的系统,则为 true

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

如果调用此方法并且尚未调用 response.writeHead(),则将切换到隐式响应头模式并刷新隐式响应头。

这会发送一块响应主体。 可以多次调用该方法以提供连续的响应主体片段。

http 模块中,当请求是 HEAD 请求时,则省略响应主体。 同样地, 204304 响应不得包含消息主体。

chunk 可以是字符串或 buffer。 如果 chunk 是一个字符串,则第二个参数指定如何将其编码为字节流。 当刷新此数据块时将调用 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 作为第二个参数。

返回对 ServerResponse 的引用,以便可以链式调用。

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

此方法只能在消息上调用一次,并且必须在调用 response.end() 之前调用。

如果在调用此方法之前调用了 response.write()response.end(),则将计算隐式或可变的响应头并调用此函数。

当使用 response.setHeader() 设置响应头时,则与传给 response.writeHead() 的任何响应头合并,且 response.writeHead() 的优先。

如果调用此方法并且尚未调用 response.setHeader(),则直接将提供的响应头值写入网络通道而不在内部进行缓存,响应头上的 response.getHeader() 将不会产生预期的结果。 如果需要渐进的响应头填充以及将来可能的检索和修改,则改用 response.setHeader()

// 返回 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 以字节而非字符为单位。 使用 Buffer.byteLength() 来判断主体的长度(以字节为单位)。 Node.js 不检查 Content-Length 和已传输的主体的长度是否相等。

尝试设置包含无效字符的响应头字段名称或值将导致抛出 TypeError

response.writeProcessing()#

向客户端发送 HTTP/1.1 102 处理消息,表明可以发送请求主体。

http.IncomingMessage 类#

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

'aborted' 事件#

当请求中止时触发。

'close' 事件#

表明底层连接已关闭。

message.aborted#

如果请求已中止,则 message.aborted 属性为 true

message.complete#

如果已收到并成功解析完整的 HTTP 消息,则 message.complete 属性将为 true

此属性可用于判断客户端或服务器在连接终止之前是否完全传输消息:

const req = http.request({
  host: '127.0.0.1',
  port: 8080,
  method: 'POST'
}, (res) => {
  res.resume();
  res.on('end', () => {
    if (!res.complete)
      console.error(
        '消息仍在发送时终止了连接');
  });
});

message.destroy([error])#

在接收到 IncomingMessage 的套接字上调用 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-afterserveruser-agent 会被丢弃。
  • set-cookie 始终是一个数组。重复项都会添加到数组中。
  • 对于重复的 cookie 消息头,其值会使用与 '; ' 连接到一起。
  • 对于所有其他消息头,其值会使用 ', ' 连接到一起。

message.httpVersion#

在服务器请求的情况下,表示客户端发送的 HTTP 版本。 在客户端响应的情况下,表示连接到的服务器的 HTTP 版本。 可能是 '1.1''1.0'

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

message.method#

仅对从 http.Server 获取的请求有效。

请求方法为字符串。 只读。 示例:'GET''DELETE'

message.rawHeaders#

原始请求头/响应头的列表,与接收到的完全一致。

键和值位于同一列表中。 它不是元组列表。 因此,偶数偏移是键值,奇数偏移是关联的值。

消息头名称不是小写的,并且不会合并重复项。

// 打印类似于:
//
// [ 'user-agent',
//   '这是无效的,因为只能有一个值',
//   '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.socket.setTimeout(msecs, callback)

message.socket#

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

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

此属性保证是 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。

message.statusCode#

仅对从 http.ClientRequest 获取的响应有效。

3 位 HTTP 响应状态码。 例如 404

message.statusMessage#

仅对从 http.ClientRequest 获取的响应有效。

HTTP 响应状态消息(原因短语)。 例如 OKInternal Server Error

message.trailers#

请求/响应的尾部消息头对象。 仅在 'end' 事件中填充。

message.url#

仅对从 http.Server 获取的请求有效。

请求的 URL 字符串。 它仅包含实际的 HTTP 请求中存在的 URL。 以下面的请求为例:

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

要将 URL 解析成各个部分:

new URL(request.url, `http://${request.headers.host}`);

request.url'/status?name=ryan'request.headers.host'localhost:3000' 时:

$ node
> new URL(request.url, `http://${request.headers.host}`)
URL {
  href: 'http://localhost:3000/status?name=ryan',
  origin: 'http://localhost:3000',
  protocol: 'http:',
  username: '',
  password: '',
  host: 'localhost:3000',
  hostname: 'localhost',
  port: '3000',
  pathname: '/status',
  search: '?name=ryan',
  searchParams: URLSearchParams { 'name' => 'ryan' },
  hash: ''
}

http.METHODS#

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

http.STATUS_CODES#

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

http.createServer([options][, requestListener])#

  • options <Object>
    • IncomingMessage <http.IncomingMessage> 指定要使用的 IncomingMessage 类。 对于扩展原始的 IncomingMessage 很有用。 默认值: IncomingMessage
    • ServerResponse <http.ServerResponse> 指定要使用的 ServerResponse 类。 对于扩展原始的 ServerResponse 很有用。 默认值: ServerResponse
    • insecureHTTPParser <boolean> 使用不安全的 HTTP 解析器,当为 true 时可以接受无效的 HTTP 请求头。 应避免使用不安全的解析器。 详见 --insecure-http-parser默认值: false
    • maxHeaderSize <number> 可选地重写 --max-http-header-size(用于服务器接收的请求)的值,即请求头的最大长度(以字节为单位)。 默认值: 16384(16KB)。
  • requestListener <Function>
  • 返回: <http.Server>

返回新的 http.Server 实例。

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

http.get(options[, callback])#

http.get(url[, 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;
  const contentType = res.headers['content-type'];

  let error;
  // 任何 2xx 状态码都表示成功的响应,但是这里只检查 200。
  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.error(error.message);
    // 消费响应的数据来释放内存。
    res.resume();
    return;
  }

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

http.globalAgent#

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

http.maxHeaderSize#

只读属性,指定 HTTP 消息头的最大允许大小(以字节为单位)。 默认为 8KB。 可使用 --max-http-header-size 命令行选项进行配置。

通过传入 maxHeaderSize 选项,可以为服务器和客户端的请求重写此值。

http.request(options[, callback])#

http.request(url[, options][, callback])#

  • url <string> | <URL>
  • options <Object>
    • agent <http.Agent> | <boolean> 控制 Agent 的行为。可能的值有:
      • undefined (默认): 对此主机和端口使用 http.globalAgent
      • Agent 对象: 显式地使用传入的 Agent
      • false: 使用新建的具有默认值的 Agent
    • auth <string> 基本的身份验证,即 'user:password',用于计算授权请求头。
    • createConnection <Function>agent 选项未被使用时,用来为请求生成套接字或流的函数。这可用于避免创建自定义的 Agent 类以覆盖默认的 createConnection 函数。详见 agent.createConnection()。任何双工流都是有效的返回值。
    • defaultPort <number> 协议的默认端口。 如果使用 Agent,则默认值为 agent.defaultPort,否则为 undefined
    • family <number> 当解析 hosthostname 时使用的 IP 地址族。有效值为 46。如果没有指定,则同时使用 IP v4 和 v6。
    • headers <Object> 包含请求头的对象。
    • host <string> 请求发送至的服务器的域名或 IP 地址。默认值: 'localhost'
    • hostname <string> host 的别名。为了支持 url.parse(),如果同时指定 hosthostname,则使用 hostname
    • insecureHTTPParser <boolean> 使用不安全的 HTTP 解析器,当为 true 时可以接受无效的 HTTP 请求头。应避免使用不安全的解析器。详见 --insecure-http-parser默认值: false
    • localAddress <string> 为网络连接绑定的本地接口。
    • lookup <Function> 自定义的查找函数。 默认值: dns.lookup()
    • maxHeaderSize <number> 可选地重写 --max-http-header-size(用于服务器接收的请求)的值,即请求头的最大长度(以字节为单位)。 默认值: 16384(16KB)。
    • method <string> 一个字符串,指定 HTTP 请求的方法。默认值: 'GET'
    • path <string> 请求的路径。应包括查询字符串(如果有)。例如 '/index.html?page=12'。当请求的路径包含非法的字符时,则抛出异常。目前只有空格被拒绝,但未来可能会有所变化。默认值: '/'
    • port <number> 远程服务器的端口。默认值: defaultPort(如果有设置)或 80
    • protocol <string> 使用的协议。默认值: 'http:'
    • setHost <boolean>: 指定是否自动添加 Host 请求头。默认值: true
    • socketPath <string> Unix 域套接字。如果指定了 hostport 之一(它们指定了 TCP 套接字),则不能使用此选项。
    • timeout <number>: 指定套接字超时的数值,以毫秒为单位。这会在套接字被连接之前设置超时。
  • callback <Function>
  • 返回: <http.ClientRequest>

Node.js 为每个服务器维护多个连接以发出 HTTP 请求。 此函数允许显式地发出请求。

url 可以是字符串或 URL 对象。 如果 url 是一个字符串,则会自动使用 [url.URL()] 解析它。 如果它是一个 URL 对象,则会自动转换为普通的 options 对象。

如果同时指定了 urloptions,则对象会被合并,其中 options 属性优先。

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

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

const postData = querystring.stringify({
  'msg': '你好世界'
});

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

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

req.on('error', (e) => {
  console.error(`请求遇到问题: ${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' 事件的监听器。详见 RFC 2616 的第 8.2.3 节。

  • 发送授权请求头会使用 auth 选项覆盖以计算基本的身份验证。

使用 URL 作为 options 的示例:

const options = new URL('http://abc:[email protected]');

const req = http.request(options, (res) => {
  // ...
});

在成功的请求中,会按以下顺序触发以下事件:

  • 'socket' 事件
  • 'response' 事件
    • res 对象上任意次数的 'data' 事件(如果响应主体为空,则根本不会触发 'data' 事件,例如在大多数重定向中)
    • res 对象上的 'end' 事件
  • 'close' 事件

如果出现连接错误,则触发以下事件:

  • 'socket' 事件
  • 'error' 事件
  • 'close' 事件

如果收到响应之前过早关闭连接,则按以下顺序触发以下事件:

  • 'socket' 事件
  • 'error' 事件并带上错误信 'Error: socket hang up' 和错误码 'ECONNRESET'
  • 'close' 事件

如果收到响应之后过早关闭连接,则按以下顺序触发以下事件:

  • 'socket' 事件
  • 'response' 事件
    • res 对象上任意次数的 'data' 事件
  • (此处连接已关闭)
  • res 对象上的 'aborted' 事件
  • 'close'
  • res 对象上的 'close' 事件

If req.destroy() is called before a socket is assigned, the following events will be emitted in the following order:

  • (req.destroy() called here)
  • 'error' with an error with message 'Error: socket hang up' and code 'ECONNRESET'
  • 'close'

If req.destroy() is called before the connection succeeds, the following events will be emitted in the following order:

  • 'socket'
  • (req.destroy() called here)
  • 'error' with an error with message 'Error: socket hang up' and code 'ECONNRESET'
  • 'close'

If req.destroy() is called after the response is received, the following events will be emitted in the following order:

  • 'socket'
  • 'response'
    • 'data' any number of times, on the res object
  • (req.destroy() called here)
  • 'aborted' on the res object
  • 'close'
  • 'close' on the res object

If req.abort() is called before a socket is assigned, the following events will be emitted in the following order:

  • (req.abort() called here)
  • 'abort'
  • 'close'

如果在连接成功之前调用 req.abort(),则按以下顺序触发以下事件:

  • 'socket' 事件
  • (在这里调用 req.abort())
  • 'abort' 事件
  • 'error' 事件并带上错误信息 'Error: socket hang up' 和错误码 'ECONNRESET'
  • 'close' 事件

如果在响应被接收之后调用 req.abort(),则按以下顺序触发以下事件:

  • 'socket' 事件
  • 'response' 事件
    • res 对象上任意次数的 'data' 事件
  • (在这里调用 req.abort())
  • 'abort' 事件
  • res 对象上的 'aborted' 事件
  • 'close' 事件
  • res 对象上的 'end' 事件
  • res 对象上的 'close' 事件

设置 timeout 选项或使用 setTimeout() 函数不会中止请求或执行除添加 'timeout' 事件之外的任何操作。

http.validateHeaderName(name)#

Performs the low-level validations on the provided name that are done when res.setHeader(name, value) is called.

Passing illegal value as name will result in a TypeError being thrown, identified by code: 'ERR_INVALID_HTTP_TOKEN'.

It is not necessary to use this method before passing headers to an HTTP request or response. The HTTP module will automatically validate such headers. Examples:

Example:

const { validateHeaderName } = require('http');

try {
  validateHeaderName('');
} catch (err) {
  err instanceof TypeError; // --> true
  err.code; // --> 'ERR_INVALID_HTTP_TOKEN'
  err.message; // --> 'Header name must be a valid HTTP token [""]'
}

http.validateHeaderValue(name, value)#

Performs the low-level validations on the provided value that are done when res.setHeader(name, value) is called.

Passing illegal value as value will result in a TypeError being thrown.

  • Undefined value error is identified by code: 'ERR_HTTP_INVALID_HEADER_VALUE'.
  • Invalid value character error is identified by code: 'ERR_INVALID_CHAR'.

It is not necessary to use this method before passing headers to an HTTP request or response. The HTTP module will automatically validate such headers.

Examples:

const { validateHeaderValue } = require('http');

try {
  validateHeaderValue('x-my-header', undefined);
} catch (err) {
  err instanceof TypeError; // --> true
  err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'; // --> true
  err.message; // --> 'Invalid value "undefined" for header "x-my-header"'
}

try {
  validateHeaderValue('x-my-header', 'oʊmɪɡə');
} catch (err) {
  err instanceof TypeError; // --> true
  err.code === 'ERR_INVALID_CHAR'; // --> true
  err.message; // --> 'Invalid character in header content ["x-my-header"]'
}