On this page

HTTP

History
Source Code: lib/http.js

稳定性:2 - 稳定

此模块包含客户端和服务器,可以通过 require('node:http') (CommonJS) 或 import * as http from 'node:http' (ES 模块) 导入。

Node.js 中的 HTTP 接口旨在支持该协议的许多传统上难以使用的功能。 特别是大型的、可能分块编码的消息。该接口谨慎地从不缓冲整个请求或响应,以便 用户能够流式传输数据。

HTTP 消息头由如下对象表示:

{ "content-length": "123",
  "content-type": "text/plain",
  "connection": "keep-alive",
  "host": "example.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', 'example.com',
  'accepT', '*/*' ]
Attributes
options:<Object>
要在 agent 上设置的可配置选项集。 可以包含以下字段:
keepAlive:<boolean>
即使没有 未完成的请求也保留套接字,以便它们可用于未来的请求而 无需重新建立 TCP 连接。不要与  Connection 头的 keep-alive 值混淆。使用 agent 时始终发送 Connection: keep-alive 头,除非显式指定了 Connection 头,或者当 keepAlivemaxSockets 选项分别设置为 falseInfinity 时,在这种情况下 将使用 Connection: close默认值: false
keepAliveMsecs:<number>
当使用  keepAlive 选项时,指定 TCP Keep-Alive 数据包的 初始延迟 。 当 keepAlive 选项为 falseundefined 时忽略。 默认值: 1000
agentKeepAliveTimeoutBuffer:<number>
在确定套接字 过期时间时,从服务器提供的  keep-alive: timeout=... 提示中减去的毫秒数。 此缓冲区有助于确保 agent 在服务器之前稍微关闭套接字, 减少在即将被服务器关闭的套接字上发送请求的几率。 默认值: 1000
maxSockets:<number>
允许每个主机的最大套接字数。 如果同一主机打开多个并发连接,每个请求 将使用新套接字,直到达到  maxSockets 值。 如果主机尝试打开超过 maxSockets 的连接, 额外的请求将进入待处理请求队列,并在现有连接终止时 进入活动连接状态。 这确保在任何时间点,给定主机最多有 maxSockets 个活动连接。 默认值: Infinity
maxTotalSockets:<number>
允许所有主机的最大套接字总数。 每个请求将使用一个新套接字, 直到达到最大值。  默认值: Infinity
maxFreeSockets:<number>
每个主机保持在空闲状态的最大套接字数。 仅当  keepAlive 设置为 true 时相关。 默认值: 256
scheduling:<string>
选择下一个可用套接字时应用的调度策略。 可以是  'fifo''lifo' 。 两种调度策略的主要区别在于 'lifo' 选择最近使用的套接字,而 'fifo' 选择 最久未使用的套接字。 在每秒请求率较低的情况下, 'lifo' 调度 将降低选择可能因不活动而被服务器关闭的套接字的风险。 在每秒请求率较高的情况下, 'fifo' 调度将最大化打开套接字的数量, 而 'lifo' 调度将使其保持尽可能低。 默认值: 'lifo'
timeout:<number>
套接字超时时间(毫秒)。 这将在创建套接字时设置超时。
用于代理配置的环境变量。 详见  内置代理支持默认值: undefined
HTTP_PROXY:<string> | <undefined>
HTTP 请求应使用的代理服务器 URL。 如果为 undefined,HTTP 请求不使用代理。
HTTPS_PROXY:<string> | <undefined>
HTTPS 请求应使用的代理服务器 URL。 如果为 undefined,HTTPS 请求不使用代理。
指定不应通过代理路由的端点的模式。
http_proxy:<string> | <undefined>
与  HTTP_PROXY 相同。如果两者都设置, http_proxy 优先。
https_proxy:<string> | <undefined>
与  HTTPS_PROXY 相同。如果两者都设置, https_proxy 优先。
与  NO_PROXY 相同。如果两者都设置, no_proxy 优先。
defaultPort:<number>
当请求中未指定端口时使用的默认端口。 默认值: 80
protocol:<string>
agent 使用的协议。 默认值: 'http:'

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

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

import { Agent, request } from 'node:http';
const keepAliveAgent = new Agent({ keepAlive: true });
options.agent = keepAliveAgent;
request(options, onResponseCallback);
new Agent(options?): void
Attributes
options:<Object>
要在 agent 上设置的可配置选项集。 可以包含以下字段:
keepAlive:<boolean>
即使没有 未完成的请求也保留套接字,以便它们可用于未来的请求而 无需重新建立 TCP 连接。不要与  Connection 头的 keep-alive 值混淆。使用 agent 时始终发送 Connection: keep-alive 头,除非显式指定了 Connection 头,或者当 keepAlivemaxSockets 选项分别设置为 falseInfinity 时,在这种情况下 将使用 Connection: close默认值: false
keepAliveMsecs:<number>
当使用  keepAlive 选项时,指定 TCP Keep-Alive 数据包的 初始延迟 。 当 keepAlive 选项为 falseundefined 时忽略。 默认值: 1000
agentKeepAliveTimeoutBuffer:<number>
在确定套接字 过期时间时,从服务器提供的  keep-alive: timeout=... 提示中减去的毫秒数。 此缓冲区有助于确保 agent 在服务器之前稍微关闭套接字, 减少在即将被服务器关闭的套接字上发送请求的几率。 默认值: 1000
maxSockets:<number>
允许每个主机的最大套接字数。 如果同一主机打开多个并发连接,每个请求 将使用新套接字,直到达到  maxSockets 值。 如果主机尝试打开超过 maxSockets 的连接, 额外的请求将进入待处理请求队列,并在现有连接终止时 进入活动连接状态。 这确保在任何时间点,给定主机最多有 maxSockets 个活动连接。 默认值: Infinity
maxTotalSockets:<number>
允许所有主机的最大套接字总数。 每个请求将使用一个新套接字, 直到达到最大值。  默认值: Infinity
maxFreeSockets:<number>
每个主机保持在空闲状态的最大套接字数。 仅当  keepAlive 设置为 true 时相关。 默认值: 256
scheduling:<string>
选择下一个可用套接字时应用的调度策略。 可以是  'fifo''lifo' 。 两种调度策略的主要区别在于 'lifo' 选择最近使用的套接字,而 'fifo' 选择 最久未使用的套接字。 在每秒请求率较低的情况下, 'lifo' 调度 将降低选择可能因不活动而被服务器关闭的套接字的风险。 在每秒请求率较高的情况下, 'fifo' 调度将最大化打开套接字的数量, 而 'lifo' 调度将使其保持尽可能低。 默认值: 'lifo'
timeout:<number>
套接字超时时间(毫秒)。 这将在创建套接字时设置超时。
用于代理配置的环境变量。 详见  内置代理支持默认值: undefined
HTTP_PROXY:<string> | <undefined>
HTTP 请求应使用的代理服务器 URL。 如果为 undefined,HTTP 请求不使用代理。
HTTPS_PROXY:<string> | <undefined>
HTTPS 请求应使用的代理服务器 URL。 如果为 undefined,HTTPS 请求不使用代理。
指定不应通过代理路由的端点的模式。
http_proxy:<string> | <undefined>
与  HTTP_PROXY 相同。如果两者都设置, http_proxy 优先。
https_proxy:<string> | <undefined>
与  HTTPS_PROXY 相同。如果两者都设置, https_proxy 优先。
与  NO_PROXY 相同。如果两者都设置, no_proxy 优先。
defaultPort:<number>
当请求中未指定端口时使用的默认端口。 默认值: 80
protocol:<string>
agent 使用的协议。 默认值: 'http:'

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

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

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

agent.createConnection

History
agent.createConnection(options, callback?): void
Attributes
options:<Object>
包含连接详情的选项。检查  net.createConnection() 了解选项的格式。对于自定义 agent, 此对象传递给自定义 createConnection 函数。
callback:<Function>
(可选,主要用于自定义 agent)当套接字 创建时由自定义  createConnection 实现调用的函数, 特别是对于异步操作。
如果套接字创建失败则为错误对象。
创建的套接字。
返回: <stream.Duplex> 创建的套接字。这是由默认 实现或自定义同步  createConnection 实现返回的。 如果自定义 createConnection 使用 callback 进行异步 操作,此返回值可能不是获取套接字的主要方式。

产生一个用于 HTTP 请求的套接字/流。

默认情况下,此函数的行为与 net.createConnection() 完全相同, 同步返回创建的套接字。签名中的可选 callback 参数被此默认实现使用。

然而,自定义 agent 可以重写此方法以提供更大的灵活性, 例如,异步创建套接字。当重写 createConnection 时:

  1. 同步套接字创建:重写的方法可以直接返回 套接字/流。
  2. 异步套接字创建:重写的方法可以接受 callback 并将创建的套接字/流传递给它(例如,callback(null, newSocket))。 如果在套接字创建期间发生错误,应将其作为第一个 参数传递给 callback(例如,callback(err))。

agent 将使用 options 和此内部 callback 调用提供的 createConnection 函数。 agent 提供的 callback 的签名为 (err, stream)

M

agent.keepSocketAlive

History
agent.keepSocketAlive(socket): void
Attributes

socket 从请求分离并可由 Agent 持久化时调用。默认行为是:

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

此方法可被特定的 Agent 子类重写。如果此 方法返回假值,套接字将被销毁而不是持久化 以供下一个请求使用。

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

M

agent.reuseSocket

History
agent.reuseSocket(socket, request): void
Attributes

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

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

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

M

agent.destroy

History
agent.destroy(): void

销毁 agent 当前使用的任何套接字。

通常不需要这样做。但是,如果使用启用了 keepAlive 的 agent,则最好在不再需要时显式关闭 agent。否则, 套接字可能会在服务器终止它们之前保持打开很长时间。

keepAlive 启用时,包含 agent 当前等待使用的套接字数组的对象。 请勿修改。

freeSockets 列表中的套接字将在 'timeout' 时自动销毁并 从数组中移除。

agent.getName(options?): void
Attributes
options:<Object>
提供名称生成信息的一组选项
发出请求的服务器的域名或 IP 地址
远程服务器的端口
localAddress:<string>
发出请求时绑定网络连接的本机接口
family:<integer>
如果不等于  undefined ,则必须为 4 或 6。
返回: <string>

获取一组请求选项的唯一名称,以确定连接 是否可以复用。对于 HTTP agent,这将返回 host:port:localAddresshost:port:localAddress:family。对于 HTTPS agent, 名称包括 CA、cert、ciphers 和其他决定套接字可复用性的 HTTPS/TLS 特定选项。

P

agent.maxFreeSockets

History

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

P

agent.maxSockets

History

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

P

agent.maxTotalSockets

History

默认设置为 Infinity。确定 agent 可以打开多少个并发套接字。与 maxSockets 不同,此参数适用于所有源。

包含尚未分配给 套接字的请求队列的对象。请勿修改。

包含 agent 当前使用的套接字数组的对象。 请勿修改。

类:http.ClientRequest

History

此对象在内部创建并从 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' 事件不会触发。此外,在数据被读取之前,它将消耗内存,最终可能导致 '进程内存溢出' 错误。

为了向后兼容,只有在注册了 'error' 监听器的情况下,res 才会触发 'error'

设置 Content-Length 头部以限制响应体大小。如果 response.strictContentLength 设置为 trueContent-Length 头部值不匹配将导致抛出 Error,标识为 code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'

Content-Length 值应为字节数,而非字符数。使用 Buffer.byteLength() 来确定主体的字节长度。

事件:'abort'

History

稳定性:0 - 已废弃。请改为监听 'close' 事件。

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

事件:'close'

History

表示请求已完成,或其底层连接在响应完成之前被提前终止。

事件:'connect'

History
Attributes
head:
{Buffer}

每当服务器响应带有 CONNECT 方法的请求时触发。如果没有监听此事件,接收 CONNECT 方法的客户端的连接将被关闭。

除非用户指定了 <net.Socket> 以外的 socket 类型,否则保证此事件会传递一个 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类。

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

import { createServer, request } from 'node:http';
import { connect } from 'node:net';
import { URL } from 'node:url';

// 创建一个 HTTP 隧道代理
const proxy = createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
proxy.on('connect', (req, clientSocket, head) => {
  // 连接到源服务器
  const { port, hostname } = new URL(`http://${req.url}`);
  const serverSocket = 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: 'www.google.com:80',
  };

  const req = 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'

History

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

事件:'finish'

History

当请求已发送时触发。更具体地说,当请求头部和主体的最后一段已移交操作系统以便通过网络传输时,会触发此事件。这并不意味着服务器已经收到了任何内容。

事件:'information'

History
Attributes
httpVersion:<string>
httpVersionMajor:<integer>
httpVersionMinor:<integer>
statusCode:<integer>
statusMessage:<string>
headers:<Object>
rawHeaders:<string[]>

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

import { request } from 'node:http';

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

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

req.on('information', (info) => {
  console.log(`Got information prior to main response: ${info.statusCode}`);
});

101 Upgrade 状态不会触发此事件,因为它们打破了传统的 HTTP 请求/响应链,例如 web sockets、原地 TLS 升级或 HTTP 2.0。要接收 101 Upgrade 通知,请改为监听 'upgrade' 事件。

事件:'response'

History
Attributes

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

事件:'socket'

History
Attributes

除非用户指定了 <net.Socket> 以外的 socket 类型,否则保证此事件会传递一个 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类。

事件:'timeout'

History

当底层 socket 因无活动而超时时触发。这仅通知 socket 处于空闲状态。必须手动销毁请求。

另见:request.setTimeout()

事件:'upgrade'

History
Attributes
head:
{Buffer}

每当服务器响应带有升级的请求时触发。如果没有监听此事件且响应状态码为 101 Switching Protocols,接收升级头部的客户端的连接将被关闭。

除非用户指定了 <net.Socket> 以外的 socket 类型,否则保证此事件会传递一个 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类。

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

import http from 'node:http';
import process from 'node:process';

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

  stream.pipe(stream); // 回显
});

// 现在服务器正在运行
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, stream, upgradeHead) => {
    console.log('got upgraded!');
    stream.end();
    process.exit(0);
  });
});
M

request.abort

History
request.abort(): void

稳定性:0 - 已废弃:请改用 request.destroy()

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

P

request.aborted

History

稳定性:0 - 已废弃。请改用检查 request.destroyed

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

P

request.connection

History

稳定性:0 - 已废弃。请使用 request.socket

参见 request.socket

M

request.cork

History
request.cork(): void

参见 writable.cork()

request.end(data?, encoding?, callback?): void
Attributes
encoding:<string>
callback:<Function>
返回: <this>

完成发送请求。如果主体的任何部分未发送,它将把它们冲刷到流中。如果请求是分块的,这将发送终止符 '0\r\n\r\n'

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

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

request.destroy(error?): void
Attributes
error:<Error>
可选,一个随  'error' 事件触发的错误。
返回: <this>

销毁请求。可选地触发 'error' 事件,并触发 'close' 事件。调用此方法将导致响应中的剩余数据被丢弃并且 socket 被销毁。

详见 writable.destroy()

P

request.destroyed

History

在调用 request.destroy() 后为 true

详见 writable.destroyed

P

request.finished

History

稳定性:0 - 已废弃。请使用 request.writableEnded

如果调用了 request.end()request.finished 属性将为 true。如果请求是通过 http.get() 发起的,request.end() 将被自动调用。

M

request.flushHeaders

History
request.flushHeaders(): void

冲刷请求头部。

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

这通常是理想的(它节省了一次 TCP 往返),但当第一块数据直到可能更晚的时候才发送时则不然。request.flushHeaders() 绕过优化并启动请求。

M

request.getHeader

History
request.getHeader(name): void
Attributes
返回: <any>

读取请求上的一个头部。名称不区分大小写。返回值的类型取决于提供给 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' 是 number 类型
const cookie = request.getHeader('Cookie');
// 'cookie' 是 string[] 类型
M

request.getHeaderNames

History
request.getHeaderNames(): void

返回一个包含当前传出头部唯一名称的数组。所有头部名称均为小写。

request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);

const headerNames = request.getHeaderNames();
// headerNames === ['foo', 'cookie']
M

request.getHeaders

History
request.getHeaders(): void

返回当前传出头部的浅拷贝。由于使用了浅拷贝,数组值可能会被变更,而无需额外调用各种头部相关的 http 模块方法。返回对象的键是头部名称,值是相应的头部值。所有头部名称均为小写。

request.getHeaders() 方法返回的对象 原型继承自 JavaScript Object。这意味着典型的 Object 方法(如 obj.toString()obj.hasOwnProperty() 等)未定义且 将无法工作

request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);

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

request.getRawHeaderNames

History
request.getRawHeaderNames(): void

返回一个包含当前传出原始头部唯一名称的数组。头部名称返回时保留其设置的确切大小写形式。

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

const headerNames = request.getRawHeaderNames();
// headerNames === ['Foo', 'Set-Cookie']
M

request.hasHeader

History
request.hasHeader(name): void
Attributes
返回: <boolean>

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

限制最大响应头部数量。如果设置为 0,则不应用限制。

P

request.path

History
P

request.method

History
P

request.host

History
P

request.protocol

History
M

request.removeHeader

History
request.removeHeader(name): void
Attributes

移除已在头部对象中定义的头部。

P

request.reusedSocket

History
  • 类型:<boolean> 请求是否通过重用的 socket 发送。

当通过启用了 keep-alive 的 agent 发送请求时,底层 socket 可能会被重用。但如果服务器在不当时机关闭连接,客户端可能会遇到 'ECONNRESET' 错误。

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

// 服务器默认有 5 秒的 keep-alive 超时
http
  .createServer((req, res) => {
    res.write('hello\n');
    res.end();
  })
  .listen(3000);

setInterval(() => {
  // 适配一个 keep-alive agent
  http.get('http://localhost:3000', { agent }, (res) => {
    res.on('data', (data) => {
      // 什么都不做
    });
  });
}, 5000); // 每 5 秒发送一次请求,以便容易触发空闲超时

通过标记请求是否重用了 socket,我们可以基于此进行自动错误重试。

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

function retriableRequest() {
  const req = http
    .get('http://localhost:3000', { agent }, (res) => {
      // ...
    })
    .on('error', (err) => {
      // 检查是否需要重试
      if (req.reusedSocket && err.code === 'ECONNRESET') {
        retriableRequest();
      }
    });
}

retriableRequest();
M

request.setHeader

History
request.setHeader(name, value): void
Attributes
value:<any>

为头部对象设置单个头部值。如果此头部已存在于待发送的头部中,其值将被替换。此处使用字符串数组来发送多个具有相同名称的头部。非字符串值将未经修改地存储。因此,request.getHeader() 可能返回非字符串值。但是,非字符串值将被转换为字符串以便网络传输。

当值为字符串时,如果它包含 latin1 编码之外的字符,将抛出异常。

如果需要在值中传递 UTF-8 字符,请使用 RFC 8187 标准对值进行编码。

const filename = 'Rock 🎵.txt';
request.setHeader('Content-Disposition', `attachment; filename*=utf-8''${encodeURIComponent(filename)}`);
M

request.setNoDelay

History
request.setNoDelay(noDelay?): void
Attributes
noDelay:<boolean>

一旦 socket 被分配给此请求并连接,socket.setNoDelay() 将被调用。

M

request.setSocketKeepAlive

History
request.setSocketKeepAlive(enable?, initialDelay?): void
Attributes
enable:<boolean>
initialDelay:<number>

一旦 socket 被分配给此请求并连接,socket.setKeepAlive() 将被调用。

request.setTimeout(timeout, callback?): void
Attributes
timeout:<number>
请求超时前的毫秒数。
callback:<Function>
超时发生时调用的可选函数。等同于绑定到  'timeout' 事件。

一旦 socket 被分配给此请求并连接,socket.setTimeout() 将被调用。

P

request.socket

History

指向底层 socket 的引用。通常用户不希望访问此属性。特别是,由于协议解析器附加到 socket 的方式,socket 不会触发 'readable' 事件。

import http from 'node:http';
const options = {
  host: 'www.google.com',
};
const req = http.get(options);
req.end();
req.once('response', (res) => {
  const ip = req.socket.localAddress;
  const port = req.socket.localPort;
  console.log(`Your IP address is ${ip} and your source port is ${port}.`);
  // 消费响应对象
});

除非用户指定了 <net.Socket> 以外的 socket 类型,否则保证此属性是 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类。

M

request.uncork

History
request.uncork(): void

参见 writable.uncork()

P

request.writableEnded

History

在调用 request.end() 后为 true。此属性不指示数据是否已冲刷,为此请改用 request.writableFinished

P

request.writableFinished

History

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

request.write(chunk, encoding?, callback?): void
Attributes
encoding:<string>
callback:<Function>
返回: <boolean>

发送一块主体数据。此方法可以调用多次。如果未设置 Content-Length,数据将自动以 HTTP 分块传输编码进行编码,以便服务器知道数据何时结束。将添加 Transfer-Encoding: chunked 头部。必须调用 request.end() 来完成发送请求。

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

callback 参数是可选的,当这块数据被冲刷时将被调用,但仅当这块数据非空时。

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

write 函数使用空字符串或缓冲区调用时,它什么都不做并等待更多输入。

类:http.Server

History

事件:'checkContinue'

History
Attributes

每当收到带有 HTTP Expect: 100-continue 的请求时发出。 如果没有监听此事件,服务器将自动响应 100 Continue(视情况而定)。

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

当此事件被发出并处理后,'request' 事件将 不会被发出。

事件:'checkExpectation'

History
Attributes

每当收到带有 HTTP Expect 头部的请求时发出,其中 值不是 100-continue。如果没有监听此事件,服务器将 自动响应 417 Expectation Failed(视情况而定)。

当此事件被发出并处理后,'request' 事件将 不会被发出。

Attributes
exception:<Error>

如果客户端连接发出 'error' 事件,它将被转发到这里。 此事件的监听器负责关闭/销毁底层 socket。例如,人们可能希望使用 自定义 HTTP 响应更优雅地关闭 socket,而不是突然切断连接。在监听器结束之前,socket 必须被关闭或销毁

除非用户指定了 <net.Socket> 以外的 socket 类型,否则此事件保证传递一个 <net.Socket> 类的实例, 它是 <stream.Duplex> 的子类。

默认行为是尝试用 HTTP '400 Bad Request' 关闭 socket, 或者在 HPE_HEADER_OVERFLOW 错误的情况下使用 HTTP '431 Request Header Fields Too Large'。如果 socket 不可写或当前附加的 http.ServerResponse 的 头部已发送,则立即销毁它。

socket 是错误来源的 net.Socket 对象。

import http from 'node: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:当前请求的原始数据包。

在某些情况下,客户端已经收到响应和/或 socket 已经被销毁,例如 ECONNRESET 错误的情况。在 尝试向 socket 发送数据之前,最好检查它是否仍然 可写。

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'

History

当服务器关闭时发出。

事件:'connect'

History
Attributes
HTTP 请求的参数,与  'request' 事件中一样
服务器和客户端之间的网络套接字
head:
{Buffer} 隧道流的第一个数据包(可能为空)

每当客户端请求 HTTP CONNECT 方法时发出。如果没有监听此事件, 则请求 CONNECT 方法的客户端的 连接将被关闭。

除非用户指定了 <net.Socket> 以外的 socket 类型,否则此事件保证传递一个 <net.Socket> 类的实例, 它是 <stream.Duplex> 的子类。

发出此事件后,请求的 socket 将没有 'data' 事件监听器,这意味着需要绑定它以便处理 发送到该服务器上数据的数据。

事件:'connection'

History
Attributes

当建立新的 TCP 流时发出此事件。socket 通常 是 net.Socket 类型的对象。通常用户不希望 访问此事件。特别是,由于协议解析器附加到 socket 的方式,socket 不会发出 'readable' 事件。 socket 也可以在 request.socket 处访问。

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

如果在此处调用 socket.setTimeout(),当 socket 服务了一个请求后,超时将被替换为 server.keepAliveTimeout(如果 server.keepAliveTimeout 非零)。

除非用户指定了 <net.Socket> 以外的 socket 类型,否则此事件保证传递一个 <net.Socket> 类的实例, 它是 <stream.Duplex> 的子类。

事件:'dropRequest'

History
Attributes
HTTP 请求的参数,与  'request' 事件中一样
服务器和客户端之间的网络套接字

当 socket 上的请求数量达到 server.maxRequestsPerSocket 的阈值时,服务器将丢弃新请求 并发出 'dropRequest' 事件,然后向客户端发送 503

事件:'request'

History
Attributes

每当有请求时发出。每个连接可能有多个请求 (在 HTTP Keep-Alive 连接的情况下)。

Attributes
HTTP 请求的参数,与  'request' 事件中一样
服务器和客户端之间升级后的流
head:
{Buffer} 升级后的流的第一个数据包(可能为空)

每当客户端的 HTTP 升级请求被接受时发出。默认情况下 所有 HTTP 升级请求都被忽略(即只发出常规的 'request' 事件 ,坚持正常的 HTTP 请求/响应流程),除非你 监听此事件,在这种情况下它们都被接受(即发出 'upgrade' 事件,未来的通信必须直接通过原始流处理)。你可以使用 服务器 shouldUpgradeCallback 选项更精确地控制此行为。

监听此事件是可选的,客户端不能坚持协议 更改。

如果升级被 shouldUpgradeCallback 接受但没有注册事件处理程序 ,则 socket 将被销毁,导致客户端立即连接关闭。

在传入请求带有主体的罕见情况下,该主体将被 正常解析,与升级流分开,原始流数据将 仅在其完成后才开始。为了确保从流读取不会被 等待请求主体读取所阻塞,流上的任何读取将自动开始请求主体流动。如果你想读取 请求主体,请确保在开始从升级流读取之前这样做(即你附加了 'data' 监听器)。

流参数通常是请求使用的 <net.Socket> 实例,但在某些情况下(例如带有请求主体),它可能是双工 流。如果需要,你可以通过 request.socket 访问请求底层的原始连接 ,除非用户指定了另一个 socket 类型,否则它保证是 <net.Socket> 的实例。

server.close(callback?): void
Attributes
callback:<Function>

停止服务器接受新连接,并关闭所有 连接到此服务器但未发送请求或等待 响应的连接。 参见 net.Server.close()

const http = require('node:http');

const server = http.createServer({ keepAliveTimeout: 60000 }, (req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000);
// 10 秒后关闭服务器
setTimeout(() => {
  server.close(() => {
    console.log('8000 端口的服务器已成功关闭');
  });
}, 10000);
M

server.closeAllConnections

History
server.closeAllConnections(): void

关闭所有连接到此服务器的已建立 HTTP(S) 连接,包括 连接到此服务器正在发送请求或等待响应的活动连接。这 不会 销毁升级到不同 协议(如 WebSocket 或 HTTP/2)的 socket。

这是一种强制关闭所有连接的方式,应谨慎使用。 每当与 server.close 结合使用时,建议在此调用 之后 调用 server.close,以避免在此调用和调用 server.close 之间 创建新连接的竞争条件。

const http = require('node:http');

const server = http.createServer({ keepAliveTimeout: 60000 }, (req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000);
// 10 秒后关闭服务器
setTimeout(() => {
  server.close(() => {
    console.log('8000 端口的服务器已成功关闭');
  });
  // 关闭所有连接,确保服务器成功关闭
  server.closeAllConnections();
}, 10000);
M

server.closeIdleConnections

History
server.closeIdleConnections(): void

关闭所有连接到此服务器但未发送请求 或等待响应的连接。

从 Node.js 19.0.0 开始,无需结合 server.close 调用此方法来回收 keep-alive 连接。使用它不会造成任何危害, 并且对于需要支持 19.0.0 之前版本的库和应用程序来说,确保向后兼容性可能很有用。 每当与 server.close 结合使用时,建议在此调用 之后 调用 server.close,以避免在此调用和调用 server.close 之间 创建新连接的竞争条件。

const http = require('node:http');

const server = http.createServer({ keepAliveTimeout: 60000 }, (req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000);
// 10 秒后关闭服务器
setTimeout(() => {
  server.close(() => {
    console.log('8000 端口的服务器已成功关闭');
  });
  // 关闭空闲连接,例如 keep-alive 连接。一旦剩余的活动连接终止,服务器将关闭
  server.closeIdleConnections();
}, 10000);

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

如果超时过期,服务器响应状态 408,而不 将请求转发给请求监听器,然后关闭连接。

必须将其设置为非零值(例如 120 秒),以便在服务器前面没有部署反向代理的情况下保护免受 潜在的拒绝服务攻击。

server.listen(): void

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

P

server.listening

History
  • 类型:<boolean> 指示服务器是否正在监听连接。
P

server.maxHeadersCount

History

限制最大传入头部计数。如果设置为 0,将不应用限制。

  • 类型:<number> 默认值: 300000

设置从客户端接收整个请求的超时值(毫秒)。

如果超时过期,服务器响应状态 408,而不 将请求转发给请求监听器,然后关闭连接。

必须将其设置为非零值(例如 120 秒),以便在服务器前面没有部署反向代理的情况下保护免受 潜在的拒绝服务攻击。

server.setTimeout(msecs?, callback?): void
Attributes
msecs:<number>
默认值: 0(无超时)
callback:<Function>
返回: <http.Server>

设置 socket 的超时值,如果发生超时,则在 Server 对象上发出 'timeout' 事件,并将 socket 作为参数传递。

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

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

P

server.maxRequestsPerSocket

History
  • 类型:<number> 每个 socket 的请求数。 默认值: 0(无限制)

关闭 keep alive 连接之前 socket 可以处理的最大请求数。

0 将禁用限制。

当达到限制时,它将 Connection 头部值设置为 close, 但不会实际关闭连接,达到限制后发送的后续请求将获得 503 Service Unavailable 作为响应。

  • 类型:<number> 超时时间(毫秒)。 默认值: 0(无超时)

在 socket 被假定超时之前的不活动毫秒数。

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

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

P

server.keepAliveTimeout

History
  • 类型:<number> 超时时间(毫秒)。 默认值: 5000(5 秒)。

服务器在完成写入最后一个响应后,需要等待额外 传入数据的不活动毫秒数,之后 socket 将被销毁。

此超时值与 server.keepAliveTimeoutBuffer 选项结合以确定实际 socket 超时,计算方式为: socketTimeout = keepAliveTimeout + keepAliveTimeoutBuffer 如果在 keep-alive 超时触发之前服务器收到新数据,它 将重置常规不活动超时,即 server.timeout

0 将禁用传入连接的 keep-alive 超时行为。 值 0 使 HTTP 服务器行为类似于 8.0.0 之前的 Node.js 版本, 后者没有 keep-alive 超时。

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

P

server.keepAliveTimeoutBuffer

History
  • 类型:<number> 超时时间(毫秒)。 默认值: 1000(1 秒)。

添加到 server.keepAliveTimeout 的额外缓冲时间,以延长内部 socket 超时。

此缓冲有助于通过略微增加超过广告 keep-alive 超时的 socket 超时时间来减少连接重置 (ECONNRESET) 错误。

此选项仅适用于新的传入连接。

server[Symbol.asyncDispose](): void

调用 server.close() 并返回一个 promise,当 服务器关闭时该 promise 会被履行。

类:http.ServerResponse

History

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

事件:'close'

History

表示响应已完成,或其底层连接在响应完成之前被提前终止。

事件:'finish'

History

当响应已发送时触发。更具体地说,当响应头部和主体的最后一段已移交操作系统以便通过网络传输时,会触发此事件。这并不意味着客户端已经收到任何内容。

M

response.addTrailers

History
response.addTrailers(headers): void
Attributes
headers:<Object>

此方法将 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

P

response.connection

History

稳定性:0 - 已弃用。使用 response.socket

参见 response.socket

M

response.cork

History
response.cork(): void

参见 writable.cork()

response.end(data?, encoding?, callback?): void
Attributes
encoding:<string>
callback:<Function>
返回: <this>

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

如果指定了 data,其效果类似于调用 response.write(data, encoding) 后跟 response.end(callback)

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

P

response.finished

History

稳定性:0 - 已弃用。使用 response.writableEnded

如果已调用 response.end(),则 response.finished 属性将为 true

M

response.flushHeaders

History
response.flushHeaders(): void

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

M

response.getHeader

History
response.getHeader(name): void
Attributes

读取已排队但尚未发送给客户端的头部。名称不区分大小写。返回值的类型取决于提供给 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 是 number 类型
const setCookie = response.getHeader('set-cookie');
// setCookie 是 string[] 类型
M

response.getHeaderNames

History
response.getHeaderNames(): void

返回一个包含当前传出头部唯一名称的数组。所有头部名称均为小写。

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

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

response.getHeaders

History
response.getHeaders(): void

返回当前传出头部的浅拷贝。由于使用的是浅拷贝,数组值可以在不调用各种头部相关的 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'] }
M

response.hasHeader

History
response.hasHeader(name): void
Attributes
返回: <boolean>

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

P

response.headersSent

History

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

M

response.removeHeader

History
response.removeHeader(name): void
Attributes

移除排队等待隐式发送的头部。

P

response.req

History

对原始 HTTP request 对象的引用。

P

response.sendDate

History

当为 true 时,如果头部中尚未存在 Date 头部,则会自动生成并在响应中发送 Date 头部。默认为 true。

这应仅用于测试;大多数 HTTP 响应都需要 Date 头部(详见 RFC 9110 Section 6.6.1)。

M

response.setHeader

History
response.setHeader(name, value): void
Attributes

返回响应对象。

为隐式头部设置单个头部值。如果此头部已存在于待发送的头部中,其值将被替换。此处使用字符串数组来发送多个具有相同名称的头部。非字符串值将未经修改地存储。因此,response.getHeader() 可能返回非字符串值。但是,非字符串值将在网络传输时转换为字符串。返回相同的响应对象给调用者,以启用链式调用。

尝试设置包含无效字符的头部字段名或值将导致抛出 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()

M

response.setTimeout

History
response.setTimeout(msecs, callback?): void
Attributes

将 Socket 的超时值设置为 msecs。如果提供了 callback,则它作为监听器添加到响应对象的 'timeout' 事件上。

如果未将 'timeout' 监听器添加到请求、响应或服务器,则套接字在超时时会被销毁。如果处理程序分配给了请求、响应或服务器的 'timeout' 事件,则必须显式处理超时的套接字。

P

response.socket

History

对底层 socket 的引用。通常用户不希望访问此属性。特别是,由于协议解析器附加到 socket 的方式,socket 不会发出 'readable' 事件。在 response.end() 之后,该属性被置空。

import http from 'node:http';
const server = http.createServer((req, res) => {
  const ip = res.socket.remoteAddress;
  const port = res.socket.remotePort;
  res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);

除非用户指定了 <net.Socket> 以外的 socket 类型,否则此属性保证是 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类。

P

response.statusCode

History

当使用隐式头部(未显式调用 response.writeHead())时,此属性控制在刷新头部时发送给客户端的状态码。

在响应头部发送给客户端后,此属性指示发出的状态码。

P

response.statusMessage

History

当使用隐式头部(未显式调用 response.writeHead())时,此属性控制在刷新头部时发送给客户端的状态消息。如果此属性保持为 undefined,则将使用该状态码的标准消息。

在响应头部发送给客户端后,此属性指示发出的状态消息。

P

response.strictContentLength

History

如果设置为 true,Node.js 将检查 Content-Length 头部值与主体大小(以字节为单位)是否相等。Content-Length 头部值不匹配将导致抛出 Error,标识为 code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'

M

response.uncork

History
response.uncork(): void

参见 writable.uncork()

P

response.writableEnded

History

在调用 response.end() 之后为 true。此属性不指示数据是否已刷新,为此请使用 response.writableFinished

P

response.writableFinished

History

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

response.write(chunk, encoding?, callback?): void
Attributes
encoding:<string>
默认: 'utf8'
callback:<Function>
返回: <boolean>

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

这发送响应主体的一块。可以多次调用此方法以提供主体的连续部分。

如果在 createServer 中将 rejectNonStandardBodyWrites 设置为 true,则当请求方法或响应状态不支持内容时,不允许写入主体。如果尝试为 HEAD 请求写入主体或作为 204304 响应的一部分写入主体,则会抛出代码为 ERR_HTTP_BODY_NOT_ALLOWED 的同步 Error

chunk 可以是字符串或 buffer。如果 chunk 是字符串,则第二个参数指定如何将其编码为字节流。当这块数据被刷新时,将调用 callback

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

第一次调用 response.write() 时,它将把缓冲的头部信息和第一块主体发送给客户端。第二次调用 response.write() 时,Node.js 假设数据将被流式传输,并单独发送新数据。也就是说,响应被缓冲到主体的第一块。

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

M

response.writeContinue

History
response.writeContinue(): void

向客户端发送 HTTP/1.1 100 Continue 消息,表示应发送请求主体。参见 Server 上的 'checkContinue' 事件。

response.writeEarlyHints(hints, callback?): void
Attributes
hints:<Object>
callback:<Function>

向客户端发送带有 Link 头部的 HTTP/1.1 103 Early Hints 消息,指示用户代理可以预加载/预连接链接的资源。hints 是一个对象,包含要随 early hints 消息发送的头部值。可选的 callback 参数将在写入响应消息时调用。

示例

const earlyHintsLink = '</styles.css>; rel=preload; as=style';
response.writeEarlyHints({
  'link': earlyHintsLink,
});

const earlyHintsLinks = [
  '</styles.css>; rel=preload; as=style',
  '</scripts.js>; rel=preload; as=script',
];
response.writeEarlyHints({
  'link': earlyHintsLinks,
  'x-trace-id': 'id for diagnostics',
});

const earlyHintsCallback = () => console.log('early hints message sent');
response.writeEarlyHints({
  'link': earlyHintsLinks,
}, earlyHintsCallback);
response.writeHead(statusCode, statusMessage?, headers?): void
Attributes
statusCode:<number>
statusMessage:<string>
headers:<Object> | <Array>

向请求发送响应头。状态码是 3 位 HTTP 状态码,如 404。最后一个参数 headers 是响应头。可选地,可以将人类可读的 statusMessage 作为第二个参数给出。

headers 可以是一个 Array,其中键和值在同一列表中。它 不是 元组列表。因此,偶数偏移量是键值,奇数偏移量是关联值。数组格式与 request.rawHeaders 相同。

返回对 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

M

response.writeProcessing

History
response.writeProcessing(): void

向客户端发送 HTTP/1.1 102 Processing 消息,表示应发送请求主体。

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

与其 socket 值(<stream.Duplex> 的子类)不同,IncomingMessage 本身继承自 <stream.Readable> 并单独创建,用于解析和发出传入的 HTTP 头部和负载,因为底层 socket 可能在保持活动的情况下被多次重用。

事件:'aborted'

History

稳定性:0 - 已弃用。请改为监听 'close' 事件。

当请求被中止时发出。

当请求完成时发出。

P

message.aborted

History

稳定性:0 - 已弃用。请检查 <stream.Readable> 中的 message.destroyed

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

P

message.complete

History

如果完整的 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(
        '消息仍在发送时连接被终止');
  });
});
P

message.connection

History

稳定性:0 - 已弃用。使用 message.socket

message.socket 的别名。

message.destroy(error?): void
Attributes
error:<Error>
返回: <this>

在接收 IncomingMessage 的 socket 上调用 destroy()。如果提供了 error,则在 socket 上发出 'error' 事件,并将 error 作为参数传递给该事件的任何监听器。

请求/响应头部对象。

头部名称和值的键值对。头部名称为小写。

// 打印类似以下内容:
//
// { '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 的重复项将被丢弃。 要允许上述列出的头部重复值被连接,请在 http.request()http.createServer() 中使用 joinDuplicateHeaders 选项。有关更多信息,请参阅 RFC 9110 第 5.3 节。
  • set-cookie 始终是一个数组。重复项会被添加到数组中。
  • 对于重复的 cookie 头部,值用 ; 连接在一起。
  • 对于所有其他头部,值用 , 连接在一起。
P

message.headersDistinct

History

类似于 message.headers,但没有连接逻辑,且值始终是字符串数组,即使对于只接收一次的头部也是如此。

// 打印类似以下内容:
//
// { 'user-agent': ['curl/7.22.0'],
//   host: ['127.0.0.1:8000'],
//   accept: ['*/*'] }
console.log(request.headersDistinct);
P

message.httpVersion

History

如果是服务器请求,则为客户端发送的 HTTP 版本。如果是客户端响应,则为所连接服务器的 HTTP 版本。 可能是 '1.1''1.0'

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

P

message.method

History

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

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

P

message.rawHeaders

History

原始请求/响应头部列表,完全按照接收到的样子。

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

头部名称不大写,重复项不合并。

// 打印类似以下内容:
//
// [ 'user-agent',
//   '这是无效的,因为只能有一个',
//   'User-Agent',
//   'curl/7.22.0',
//   'Host',
//   '127.0.0.1:8000',
//   'ACCEPT',
//   '*/*' ]
console.log(request.rawHeaders);
P

message.rawTrailers

History

原始请求/响应尾部键和值,完全按照接收到的样子。仅在 'end' 事件处填充。

M

message.setTimeout

History
message.setTimeout(msecs, callback?): void
Attributes

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

P

message.socket

History

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

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

除非用户指定了 <net.Socket> 以外的 socket 类型或在内部设为空,否则此属性保证是 <net.Socket> 类(<stream.Duplex> 的子类)的实例。

P

message.statusCode

History

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

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

P

message.statusMessage

History

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

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

P

message.trailers

History

请求/响应尾部对象。仅在 'end' 事件处填充。

P

message.trailersDistinct

History

类似于 message.trailers,但没有连接逻辑,且值始终是字符串数组,即使对于只接收一次的头部也是如此。 仅在 'end' 事件处填充。

P

message.url

History

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

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

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

要将 URL 解析为其组成部分:

request.url'/status?name=ryan'process.env.HOST 为 undefined 时:

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

确保将 process.env.HOST 设置为服务器的主机名,或者考虑完全替换此部分。如果使用 req.headers.host,请确保使用适当的验证,因为客户端可能会指定自定义 Host 头部。

类:http.OutgoingMessage

History
  • 继承自:{Stream}

此类作为 http.ClientRequesthttp.ServerResponse 的父类。从 HTTP 事务参与者的角度来看,它是一个抽象的传出消息。

事件:'drain'

History

当消息的缓冲区再次空闲时发出。

事件:'finish'

History

当传输成功完成时发出。

事件:'prefinish'

History

在调用 outgoingMessage.end() 后发出。 发出事件时,所有数据都已处理完毕,但不一定完全刷新。

M

outgoingMessage.addTrailers

History
outgoingMessage.addTrailers(headers): void
Attributes
headers:<Object>

将 HTTP 尾部(头部但在消息末尾)添加到消息中。

仅当消息采用分块编码时,才会发出尾部。否则,尾部将被静默丢弃。

HTTP 要求发送 Trailer 头部以发出尾部,其值中包含头部字段名称列表,例如:

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

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

M

outgoingMessage.appendHeader

History
outgoingMessage.appendHeader(name, value): void
Attributes
头部名称
头部值
返回: <this>

将单个头部值附加到头部对象。

如果值是数组,则相当于多次调用此方法。

如果该头部之前没有值,则相当于调用 outgoingMessage.setHeader(name, value)

根据创建客户端请求或服务器时 options.uniqueHeaders 的值,这将导致头部被发送多次,或者单次发送且值用 ; 连接。

P

outgoingMessage.connection

History

稳定性:0 - 已弃用:请改用 outgoingMessage.socket

outgoingMessage.socket 的别名。

M

outgoingMessage.cork

History
outgoingMessage.cork(): void

参见 writable.cork()

M

outgoingMessage.destroy

History
outgoingMessage.destroy(error?): void
Attributes
error:<Error>
可选,随  error 事件发出的错误
返回: <this>

销毁消息。一旦 socket 与消息关联并连接,该 socket 也将被销毁。

M

outgoingMessage.end

History
outgoingMessage.end(chunk, encoding?, callback?): void
Attributes
encoding:<string>
可选, 默认utf8
callback:<Function>
可选
返回: <this>

完成传出消息。如果有任何主体部分未发送,它将把它们刷新到底层系统。如果消息是分块的,它将发送终止块 0\r\n\r\n,并发送尾部(如果有)。

如果指定了 chunk,则相当于调用 outgoingMessage.write(chunk, encoding),然后调用 outgoingMessage.end(callback)

如果提供了 callback,它将在消息完成时调用(相当于 'finish' 事件的监听器)。

M

outgoingMessage.flushHeaders

History
outgoingMessage.flushHeaders(): void

刷新消息头部。

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

这通常是希望的(它节省了一次 TCP 往返),但当第一块数据直到可能更晚才发送时则不然。outgoingMessage.flushHeaders() 绕过优化并启动消息。

M

outgoingMessage.getHeader

History
outgoingMessage.getHeader(name): void
Attributes
头部名称

获取给定名称的 HTTP 头部的值。如果未设置该头部,返回值将为 undefined

M

outgoingMessage.getHeaderNames

History
outgoingMessage.getHeaderNames(): void

返回一个包含当前传出头部唯一名称的数组。所有名称均为小写。

M

outgoingMessage.getHeaders

History
outgoingMessage.getHeaders(): void

返回当前传出头部的浅拷贝。由于使用的是浅拷贝,数组值可能会被修改,而无需额外调用各种头部相关的 HTTP 模块方法。返回对象的键是头部名称,值是相应的头部值。所有头部名称均为小写。

outgoingMessage.getHeaders() 方法返回的对象不从 JavaScript Object 原型继承。这意味着典型的 Object 方法(如 obj.toString()obj.hasOwnProperty() 等)未定义且无法工作。

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

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

outgoingMessage.hasHeader

History
outgoingMessage.hasHeader(name): void
Attributes
返回: <boolean>

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

P

outgoingMessage.headersSent

History

只读。如果已发送头部,则为 true,否则为 false

M

outgoingMessage.pipe

History
outgoingMessage.pipe(): void

覆盖从遗留 Stream 类(http.OutgoingMessage 的父类)继承的 stream.pipe() 方法。

调用此方法将抛出 Error,因为 outgoingMessage 是只写流。

M

outgoingMessage.removeHeader

History
outgoingMessage.removeHeader(name): void
Attributes
头部名称

移除排队等待隐式发送的头部。

M

outgoingMessage.setHeader

History
outgoingMessage.setHeader(name, value): void
Attributes
头部名称
头部值
返回: <this>

设置单个头部值。如果该头部已存在于待发送头部中,其值将被替换。使用字符串数组发送多个同名的头部。

M

outgoingMessage.setHeaders

History
outgoingMessage.setHeaders(headers): void
Attributes
headers:<Headers> | <Map>
返回: <this>

为隐式头部设置多个头部值。 headers 必须是 HeadersMap 的实例, 如果头部已存在于待发送头部中, 其值将被替换。

const headers = new Headers({ foo: 'bar' });
outgoingMessage.setHeaders(headers);

const headers = new Map([['foo', 'bar']]);
outgoingMessage.setHeaders(headers);

当使用 outgoingMessage.setHeaders() 设置头部时, 它们将与传递给 response.writeHead() 的任何头部合并, 传递给 response.writeHead() 的头部具有优先级。

// 返回 content-type = text/plain
const server = http.createServer((req, res) => {
  const headers = new Headers({ 'Content-Type': 'text/html' });
  res.setHeaders(headers);
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('ok');
});
M

outgoingMessage.setTimeout

History
outgoingMessage.setTimeout(msecs, callback?): void
Attributes
msecs:<number>
callback:<Function>
超时发生时调用的可选函数。与绑定到  timeout 事件相同。
返回: <this>

一旦 socket 与消息关联并连接, socket.setTimeout() 将被调用,msecs 作为第一个参数。

P

outgoingMessage.socket

History

底层 socket 的引用。通常,用户不希望访问此属性。

调用 outgoingMessage.end() 后,此属性将被设为空。

M

outgoingMessage.uncork

History
outgoingMessage.uncork(): void

参见 writable.uncork()

P

outgoingMessage.writableCorked

History

outgoingMessage.cork() 被调用的次数。

P

outgoingMessage.writableEnded

History

如果已调用 outgoingMessage.end(),则为 true。此属性不指示数据是否已刷新。为此,请改用 message.writableFinished

P

outgoingMessage.writableFinished

History

如果所有数据都已刷新到底层系统,则为 true

P

outgoingMessage.writableHighWaterMark

History

如果已分配,则为底层 socket 的 highWaterMark。否则,为 writable.write() 开始返回 false 时的默认缓冲区级别(16384)。

P

outgoingMessage.writableLength

History

缓冲字节的数量。

P

outgoingMessage.writableObjectMode

History

始终为 false

M

outgoingMessage.write

History
outgoingMessage.write(chunk, encoding?, callback?): void
Attributes
encoding:<string>
默认utf8
callback:<Function>
返回: <boolean>

发送一块主体。此方法可以调用多次。

仅当 chunk 为字符串时,encoding 参数才相关。默认为 'utf8'

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

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

P

http.METHODS

History

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

P

http.STATUS_CODES

History

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

http.createServer(options?, requestListener?): void
Attributes
options:<Object>
connectionsCheckingInterval:
:设置检查不完整请求中的请求和头部超时的间隔值(毫秒)。 默认值: 30000
headersTimeout:
:设置从客户端接收完整 HTTP 头部的超时值(毫秒)。 有关更多信息,请参阅 server.headersTimeout默认值: 60000
highWaterMark:<number>
可选地覆盖所有  socketreadableHighWaterMarkwritableHighWaterMark 。这会影响 IncomingMessageServerResponsehighWaterMark 属性。 默认值: 请参阅 stream.getDefaultHighWaterMark()
insecureHTTPParser:<boolean>
如果设置为  true ,它将使用启用了宽容标志的 HTTP 解析器。应避免使用不安全的解析器。 有关更多信息,请参阅 --insecure-http-parser默认值: false
IncomingMessage:<http.IncomingMessage>
指定要使用的  IncomingMessage 类。对于扩展原始 IncomingMessage 很有用。 默认值: IncomingMessage
joinDuplicateHeaders:<boolean>
如果设置为  true ,此选项允许 将请求中多个头部的字段行值用逗号( , )连接,而不是丢弃重复项。 有关更多信息,请参阅 message.headers默认值: false
keepAlive:<boolean>
如果设置为  true ,它会在收到新的传入连接后立即在 socket 上启用 keep-alive 功能, 类似于在 [ socket.setKeepAlive([enable][, initialDelay]) ][ socket.setKeepAlive(enable, initialDelay) ] 中所做的。 默认值: false
keepAliveInitialDelay:<number>
如果设置为正数,它设置在空闲 socket 上发送第一个 keepalive 探测之前的初始延迟。  默认值: 0
keepAliveTimeout:
:服务器在完成写入最后一个响应后,需要等待额外传入数据的非活动毫秒数,之后 socket 将被销毁。 有关更多信息,请参阅 server.keepAliveTimeout默认值: 5000
maxHeaderSize:<number>
可选地覆盖此服务器接收请求的  --max-http-header-size 的值,即请求头部的最大长度(字节)。 默认值: 16384 (16 KiB)。
noDelay:<boolean>
如果设置为  true ,它会在收到新的传入连接后立即禁用 Nagle 算法的使用。 默认值: true
requestTimeout:
:设置从客户端接收整个请求的超时值(毫秒)。 有关更多信息,请参阅 server.requestTimeout默认值: 300000
requireHostHeader:<boolean>
如果设置为  true ,它强制服务器对任何缺少 Host 头部的 HTTP/1.1 请求消息响应 400 (Bad Request) 状态码 (根据规范强制要求)。 默认值: true
ServerResponse:<http.ServerResponse>
指定要使用的  ServerResponse 类 。对于扩展原始 ServerResponse 很有用。 默认值: ServerResponse
shouldUpgradeCallback(request):<Function>
一个回调,接收传入请求并返回布尔值,以控制应接受哪些升级尝试。接受的升级将触发  'upgrade' 事件(或者如果没有注册监听器,它们的 socket 将被销毁),而被拒绝的升级将像任何非升级请求一样触发 'request' 事件。此选项默认为 () => server.listenerCount('upgrade') > 0
uniqueHeaders:<Array>
应只发送一次的响应头列表。如果头部的值是数组,项将使用  ; 连接。
rejectNonStandardBodyWrites:<boolean>
如果设置为  true ,则在写入没有正文的 HTTP 响应时会抛出错误。 默认值: false
optimizeEmptyRequests:<boolean>
如果设置为  true ,没有 Content-LengthTransfer-Encoding 头部(表示没有正文)的请求将使用已结束的正文流初始化,因此它们永远不会发出任何流事件 (如 'data''end' )。你可以使用 req.readableEnded 来检测这种情况。 默认值: false
requestListener:<Function>
返回值: <http.Server>

返回 http.Server 的新实例。

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

import http from 'node:http';

// 创建一个本地服务器来接收数据
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000);
http.get(options, callback?): void
http.get(url, options?, callback?): void
Attributes
options:<Object>
接受与  http.request() 相同的 options ,默认方法设置为 GET。
callback:<Function>

由于大多数请求都是没有正文的 GET 请求,Node.js 提供了这个便捷方法。此方法与 http.request() 的唯一区别在于,它默认将方法设置为 GET 并自动调用 req.end()。出于 http.ClientRequest 部分所述的原因,回调必须注意消耗响应数据。

使用单个参数调用 callback,该参数是 http.IncomingMessage 的实例。

JSON 获取示例:

http.get('http://localhost:8000/', (res) => {
  const { statusCode } = res;
  const contentType = res.headers['content-type'];

  let error;
  // 任何 2xx 状态码都表示响应成功,但
  // 这里我们只检查 200。
  if (statusCode !== 200) {
    error = new Error('Request Failed.\n' +
                      `Status Code: ${statusCode}`);
  } else if (!/^application\/json/.test(contentType)) {
    error = new Error('Invalid content-type.\n' +
                      `Expected application/json but received ${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(`Got error: ${e.message}`);
});

// 创建一个本地服务器来接收数据
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000);

Agent 的全局实例,用作所有 HTTP 客户端请求的默认值。与默认 Agent 配置不同的是,它启用了 keepAlivetimeout 为 5 秒。

P

http.maxHeaderSize

History

只读属性,指定 HTTP 头部的最大允许大小(字节)。默认为 16 KiB。可使用 --max-http-header-size CLI 选项进行配置。

可以通过传递 maxHeaderSize 选项来覆盖服务器和客户端请求的此设置。

http.request(options, callback?): void
http.request(url, options?, callback?): void
Attributes
options:<Object>
控制  Agent 行为。可能的值:
undefined:
(默认):为此主机和端口使用 http.globalAgent
Agent:
对象:显式使用传入的 Agent
false:
:导致使用默认值创建新的 Agent
基本认证( 'user:password' ),用于计算 Authorization 头部。
createConnection:<Function>
当未使用  agent 选项时,产生用于请求的套接字/流的函数。这可用于避免仅为了覆盖默认 createConnection 函数而创建自定义 Agent 类。详见 agent.createConnection() 。任何 Duplex 流都是有效的返回值。
defaultPort:<number>
协议的默认端口。 默认: 如果使用了 Agent 则为 agent.defaultPort ,否则为 undefined
family:<number>
解析  hosthostname 时使用的 IP 地址族。有效值为 46 。未指定时,将同时使用 IP v4 和 v6。
headers:<Object> | <Array>
包含请求头部的对象或字符串数组。数组格式与  message.rawHeaders 相同。
hints:<number>
可选的 [ dns.lookup() 提示][]。
发出请求的服务器的域名或 IP 地址。 默认: 'localhost'
hostname:<string>
host 的别名。为了支持 url.parse() ,如果同时指定了 hosthostname ,将使用 hostname
insecureHTTPParser:<boolean>
如果设置为  true ,将使用启用了宽松标志的 HTTP 解析器。应避免使用不安全的解析器。详见 --insecure-http-parser默认: false
joinDuplicateHeaders:<boolean>
它将请求中多个头部的字段行值用  , 连接起来,而不是丢弃重复项。详见 message.headers默认: false
localAddress:<string>
用于网络连接绑定的本地接口。
localPort:<number>
用于连接的本地端口。
lookup:<Function>
自定义查找函数。 默认: dns.lookup()
maxHeaderSize:<number>
可选地覆盖  --max-http-header-size 的值(服务器接收到的响应头部的最大长度,字节)。 默认: 16384 (16 KiB)。
method:<string>
指定 HTTP 请求方法的字符串。 默认: 'GET'
请求路径。如有查询字符串应包含在内。例如: '/index.html?page=12' 。当请求路径包含非法字符时会抛出异常。目前,只有空格会被拒绝,但未来可能会改变。 默认: '/'
远程服务器的端口。 默认: 如果设置了 defaultPort 则为 defaultPort ,否则为 80
protocol:<string>
使用的协议。 默认: 'http:'
setDefaultHeaders:<boolean>
:指定是否自动添加默认头部,如  ConnectionContent-LengthTransfer-EncodingHost 。如果设置为 false ,则必须手动添加所有必要的头部。默认为 true
setHost:<boolean>
:指定是否自动添加  Host 头部。如果提供,此项将覆盖 setDefaultHeaders 。默认为 true
:一个可用于中止正在进行的请求的 AbortSignal。
socketPath:<string>
Unix 域套接字。如果指定了  hostport 之一,则不能使用此项,因为它们指定的是 TCP 套接字。
timeout:<number>
:一个数字,指定套接字超时时间(毫秒)。这将在套接字连接之前设置超时。
uniqueHeaders:<Array>
应只发送一次的请求头部列表。如果头部的值是数组,项将使用  ; 连接。
callback:<Function>

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

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

url 可以是字符串或 URL 对象。如果 url 是字符串,它将使用 new URL() 自动解析。如果它是 URL 对象,它将自动转换为普通的 options 对象。

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

可选的 callback 参数将作为 'response' 事件的一次性监听器添加。

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

import http from 'node:http';
import { Buffer } from 'node:buffer';

const postData = JSON.stringify({
  'msg': 'Hello World!',
});

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

const 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(`BODY: ${chunk}`);
  });
  res.on('end', () => {
    console.log('No more data in response.');
  });
});

req.on('error', (e) => {
  console.error(`problem with request: ${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 节。

  • 发送 Authorization 头部将覆盖使用 auth 选项来计算基本认证。

使用 URL 作为 options 的示例:

const options = new URL('http://abc:xyz@example.com');

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

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

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

在连接错误的情况下,将发出以下事件:

  • 'socket'
  • 'error'
  • 'close'

在响应接收之前连接过早关闭的情况下,将按以下顺序发出以下事件:

  • 'socket'
  • 'error' 带有消息 'Error: socket hang up' 和代码 'ECONNRESET' 的错误
  • 'close'

在响应接收之后连接过早关闭的情况下,将按以下顺序发出以下事件:

  • 'socket'
  • 'response'
    • 'data' 任意次数,在 res 对象上
  • (此处连接关闭)
  • 'aborted'res 对象上
  • 'close'
  • 'error'res 对象上,带有消息 'Error: aborted' 和代码 'ECONNRESET' 的错误
  • 'close'res 对象上

如果在分配套接字之前调用了 req.destroy(),将按以下顺序发出以下事件:

  • (此处调用了 req.destroy()
  • 'error' 带有消息 'Error: socket hang up' 和代码 'ECONNRESET' 的错误,或调用 req.destroy() 时使用的错误
  • 'close'

如果在连接成功之前调用了 req.destroy(),将按以下顺序发出以下事件:

  • 'socket'
  • (此处调用了 req.destroy()
  • 'error' 带有消息 'Error: socket hang up' 和代码 'ECONNRESET' 的错误,或调用 req.destroy() 时使用的错误
  • 'close'

如果在接收到响应之后调用了 req.destroy(),将按以下顺序发出以下事件:

  • 'socket'
  • 'response'
    • 'data' 任意次数,在 res 对象上
  • (此处调用了 req.destroy()
  • 'aborted'res 对象上
  • 'close'
  • 'error'res 对象上,带有消息 'Error: aborted' 和代码 'ECONNRESET' 的错误,或调用 req.destroy() 时使用的错误
  • 'close'res 对象上

如果在分配套接字之前调用了 req.abort(),将按以下顺序发出以下事件:

  • (此处调用了 req.abort()
  • 'abort'
  • 'close'

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

  • 'socket'
  • (此处调用了 req.abort()
  • 'abort'
  • 'error' 带有消息 'Error: socket hang up' 和代码 'ECONNRESET' 的错误
  • 'close'

如果在接收到响应之后调用了 req.abort(),将按以下顺序发出以下事件:

  • 'socket'
  • 'response'
    • 'data' 任意次数,在 res 对象上
  • (此处调用了 req.abort()
  • 'abort'
  • 'aborted'res 对象上
  • 'error'res 对象上,带有消息 'Error: aborted' 和代码 'ECONNRESET' 的错误。
  • 'close'
  • 'close'res 对象上

设置 timeout 选项或使用 setTimeout() 函数不会中止请求,除了添加 'timeout' 事件外不做任何事。

传递 AbortSignal 然后在相应的 AbortController 上调用 abort() 将与在请求上调用 .destroy() 的行为相同。具体来说,将发出 'error' 事件,错误消息为 'AbortError: The operation was aborted',代码为 'ABORT_ERR',以及 cause(如果提供了的话)。

http.validateHeaderName(name, label?): void
Attributes
label:<string>
错误消息的标签。 默认值: 'Header name'

对提供的 name 执行低级验证,这些验证会在调用 res.setHeader(name, value) 时进行。

传递非法的 name 值将导致抛出 TypeError,标识为 code: 'ERR_INVALID_HTTP_TOKEN'

在将头信息传递给 HTTP 请求或响应之前,不必使用此方法。HTTP 模块将自动验证此类头信息。

示例:

import { validateHeaderName } from 'node:http';

try {
  validateHeaderName('');
} catch (err) {
  console.error(err instanceof TypeError); // --> true
  console.error(err.code); // --> 'ERR_INVALID_HTTP_TOKEN'
  console.error(err.message); // --> 'Header 名称必须是有效的 HTTP 令牌 [""]'
}
M

http.validateHeaderValue

History
http.validateHeaderValue(name, value): void
Attributes
value:<any>

对提供的 value 执行低级验证,这些验证会在调用 res.setHeader(name, value) 时进行。

传递非法的 value 值将导致抛出 TypeError

  • Undefined 值错误标识为 code: 'ERR_HTTP_INVALID_HEADER_VALUE'
  • 无效值字符错误标识为 code: 'ERR_INVALID_CHAR'

在将头信息传递给 HTTP 请求或响应之前,不必使用此方法。HTTP 模块将自动验证此类头信息。

示例:

import { validateHeaderValue } from 'node:http';

try {
  validateHeaderValue('x-my-header', undefined);
} catch (err) {
  console.error(err instanceof TypeError); // --> true
  console.error(err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'); // --> true
  console.error(err.message); // --> '头信息 "x-my-header" 的值 "undefined" 无效'
}

try {
  validateHeaderValue('x-my-header', 'oʊmɪɡə');
} catch (err) {
  console.error(err instanceof TypeError); // --> true
  console.error(err.code === 'ERR_INVALID_CHAR'); // --> true
  console.error(err.message); // --> '头信息内容中的字符无效 ["x-my-header"]'
}
M

http.setMaxIdleHTTPParsers

History
http.setMaxIdleHTTPParsers(max): void
Attributes
默认值: 1000

设置空闲 HTTP 解析器的最大数量。

M

http.setGlobalProxyFromEnv

History
http.setGlobalProxyFromEnv(proxyEnv?): void
Attributes
proxyEnv:<Object>
包含代理配置的对象。它接受与  Agent 接受的 proxyEnv 选项相同的选项。 默认值: process.env
返回: <Function> 一个函数,用于将原始 agent 和 dispatcher 设置恢复到此  http.setGlobalProxyFromEnv() 被调用之前的状态。

动态重置全局配置,以便在运行时为 fetch()http.request()/https.request() 启用内置代理支持,作为使用 --use-env-proxy 标志或 NODE_USE_ENV_PROXY 环境变量的替代方案。它也可用于覆盖从环境变量配置的设置。

由于此函数重置全局配置,任何之前配置的 http.globalAgenthttps.globalAgent 或 undici 全局 dispatcher 在此函数被调用后将被覆盖。建议在发出任何请求之前调用它,并避免在任何请求中间调用它。

有关代理 URL 格式和 NO_PROXY 语法的详细信息,请参阅 内置代理支持

类:WebSocket

History

<WebSocket> 的浏览器兼容实现。

内置代理支持

History

稳定性:1.1 - 积极开发中

当 Node.js 创建全局 agent 时,如果 NODE_USE_ENV_PROXY 环境变量设置为 1 或启用了 --use-env-proxy,全局 agent 将使用 proxyEnv: process.env 构建,从而启用基于环境变量的代理支持。

要动态且全局地启用代理支持,请使用 http.setGlobalProxyFromEnv()

也可以通过在构建 agent 时传递 proxyEnv 选项来创建具有代理支持的自定义 agent。如果它们只想从环境变量继承配置,该值可以是 process.env,或者是具有特定设置以覆盖环境的对象。

检查 proxyEnv 的以下属性以配置代理支持。

  • HTTP_PROXYhttp_proxy:HTTP 请求的代理服务器 URL。如果两者都设置,http_proxy 优先。
  • HTTPS_PROXYhttps_proxy:HTTPS 请求的代理服务器 URL。如果两者都设置,https_proxy 优先。
  • NO_PROXYno_proxy:绕过代理的主机逗号分隔列表。如果两者都设置,no_proxy 优先。

如果请求是发往 Unix 域套接字的,代理设置将被忽略。

代理 URL 可以使用 HTTP 或 HTTPS 协议:

  • HTTP 代理:http://proxy.example.com:8080
  • HTTPS 代理:https://proxy.example.com:8080
  • 带身份验证的代理:http://username:password@proxy.example.com:8080

NO_PROXY 环境变量支持多种格式:

  • * - 绕过所有主机的代理
  • example.com - 精确主机名匹配
  • .example.com - 域名后缀匹配(匹配 sub.example.com
  • *.example.com - 通配符域名匹配
  • 192.168.1.100 - 精确 IP 地址匹配
  • 192.168.1.1-192.168.1.100 - IP 地址范围
  • example.com:8080 - 带特定端口的主机名

多个条目应由逗号分隔。

要启动一个启用了代理支持的 Node.js 进程,用于通过默认全局 agent 发送的所有请求,可以使用 NODE_USE_ENV_PROXY 环境变量:

或使用 --use-env-proxy 标志。

要使用 process.envhttp.setGlobalProxyFromEnv() 的默认选项)动态且全局地启用代理支持:

const http = require('node:http');

// 从 process.env 读取与代理相关的环境变量
const restore = http.setGlobalProxyFromEnv();

// 后续请求将使用环境变量中配置的代理
http.get('http://www.example.com', (res) => {
  // 如果设置了 HTTP_PROXY 或 http_proxy,此请求将通过代理
});

fetch('https://www.example.com', (res) => {
  // 如果设置了 HTTPS_PROXY 或 https_proxy,此请求将通过代理
});

// 要恢复原始的全局 agent 和 dispatcher 设置,请调用返回的函数。
// restore();

要使用自定义设置动态且全局地启用代理支持:

const http = require('node:http');

const restore = http.setGlobalProxyFromEnv({
  http_proxy: 'http://proxy.example.com:8080',
  https_proxy: 'https://proxy.example.com:8443',
  no_proxy: 'localhost,127.0.0.1,.internal.example.com',
});

// 后续请求将使用配置的代理
http.get('http://www.example.com', (res) => {
  // 此请求将通过 proxy.example.com:8080 进行代理
});

fetch('https://www.example.com', (res) => {
  // 此请求将通过 proxy.example.com:8443 进行代理
});

要创建具有内置代理支持的自定义 agent:

const http = require('node:http');

// 创建具有自定义代理支持的自定义 agent。
const agent = new http.Agent({ proxyEnv: { HTTP_PROXY: 'http://proxy.example.com:8080' } });

http.request({
  hostname: 'www.example.com',
  port: 80,
  path: '/',
  agent,
}, (res) => {
  // 此请求将通过 proxy.example.com:8080 使用 HTTP 协议进行代理。
  console.log(`STATUS: ${res.statusCode}`);
});

或者,以下方法也有效:

const http = require('node:http');
// 使用小写选项名。
const agent1 = new http.Agent({ proxyEnv: { http_proxy: 'http://proxy.example.com:8080' } });
// 使用从环境变量继承的值,如果进程启动时带有
// HTTP_PROXY=http://proxy.example.com:8080 这将使用 process.env.HTTP_PROXY 中指定的代理服务器。
const agent2 = new http.Agent({ proxyEnv: process.env });