HTTP
History
稳定性: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', '*/*' ]类:http.Agent
History
Add support for agentKeepAliveTimeoutBuffer.
Add support for proxyEnv.
Add support for defaultPort and protocol.
Change the default scheduling from 'fifo' to 'lifo'.
Add maxTotalSockets option to agent constructor.
Add scheduling option to specify the free socketscheduling strategy.
<Object><boolean>Connection
头的
keep-alive
值混淆。使用 agent 时始终发送
Connection: keep-alive
头,除非显式指定了
Connection
头,或者当
keepAlive
和
maxSockets
选项分别设置为
false
和
Infinity
时,在这种情况下
将使用
Connection: close
。
默认值:
false
。<number><number>keep-alive: timeout=...
提示中减去的毫秒数。
此缓冲区有助于确保 agent 在服务器之前稍微关闭套接字,
减少在即将被服务器关闭的套接字上发送请求的几率。
默认值:
1000
。<number>maxSockets
值。
如果主机尝试打开超过
maxSockets
的连接,
额外的请求将进入待处理请求队列,并在现有连接终止时
进入活动连接状态。
这确保在任何时间点,给定主机最多有
maxSockets
个活动连接。
默认值:
Infinity
。<number>Infinity
。<number>keepAlive
设置为
true
时相关。
默认值:
256
。<string>'fifo'
或
'lifo'
。
两种调度策略的主要区别在于
'lifo'
选择最近使用的套接字,而
'fifo'
选择
最久未使用的套接字。
在每秒请求率较低的情况下,
'lifo'
调度
将降低选择可能因不活动而被服务器关闭的套接字的风险。
在每秒请求率较高的情况下,
'fifo'
调度将最大化打开套接字的数量,
而
'lifo'
调度将使其保持尽可能低。
默认值:
'lifo'
。<number><Object>
|
<undefined>undefined<string>
|
<undefined><string>
|
<undefined><string>
|
<undefined><string>
|
<undefined>HTTP_PROXY
相同。如果两者都设置,
http_proxy
优先。<string>
|
<undefined>HTTPS_PROXY
相同。如果两者都设置,
https_proxy
优先。<string>
|
<undefined>NO_PROXY
相同。如果两者都设置,
no_proxy
优先。<number>80
。<string>'http:'
。socket.connect() 中的 options 也受支持。
要配置其中任何一项,必须创建自定义 http.Agent 实例。
import { Agent, request } from 'node:http';
const keepAliveAgent = new Agent({ keepAlive: true });
options.agent = keepAliveAgent;
request(options, onResponseCallback);Agent Constructor
History
Add support for agentKeepAliveTimeoutBuffer.
Add support for proxyEnv.
Add support for defaultPort and protocol.
Change the default scheduling from 'fifo' to 'lifo'.
Add maxTotalSockets option to agent constructor.
Add scheduling option to specify the free socketscheduling strategy.
new Agent(options?): void<Object><boolean>Connection
头的
keep-alive
值混淆。使用 agent 时始终发送
Connection: keep-alive
头,除非显式指定了
Connection
头,或者当
keepAlive
和
maxSockets
选项分别设置为
false
和
Infinity
时,在这种情况下
将使用
Connection: close
。
默认值:
false
。<number><number>keep-alive: timeout=...
提示中减去的毫秒数。
此缓冲区有助于确保 agent 在服务器之前稍微关闭套接字,
减少在即将被服务器关闭的套接字上发送请求的几率。
默认值:
1000
。<number>maxSockets
值。
如果主机尝试打开超过
maxSockets
的连接,
额外的请求将进入待处理请求队列,并在现有连接终止时
进入活动连接状态。
这确保在任何时间点,给定主机最多有
maxSockets
个活动连接。
默认值:
Infinity
。<number>Infinity
。<number>keepAlive
设置为
true
时相关。
默认值:
256
。<string>'fifo'
或
'lifo'
。
两种调度策略的主要区别在于
'lifo'
选择最近使用的套接字,而
'fifo'
选择
最久未使用的套接字。
在每秒请求率较低的情况下,
'lifo'
调度
将降低选择可能因不活动而被服务器关闭的套接字的风险。
在每秒请求率较高的情况下,
'fifo'
调度将最大化打开套接字的数量,
而
'lifo'
调度将使其保持尽可能低。
默认值:
'lifo'
。<number><Object>
|
<undefined>undefined<string>
|
<undefined><string>
|
<undefined><string>
|
<undefined><string>
|
<undefined>HTTP_PROXY
相同。如果两者都设置,
http_proxy
优先。<string>
|
<undefined>HTTPS_PROXY
相同。如果两者都设置,
https_proxy
优先。<string>
|
<undefined>NO_PROXY
相同。如果两者都设置,
no_proxy
优先。<number>80
。<string>'http:'
。socket.connect() 中的 options 也受支持。
要配置其中任何一项,必须创建自定义 http.Agent 实例。
import { Agent, request } from 'node:http';
const keepAliveAgent = new Agent({ keepAlive: true });
options.agent = keepAliveAgent;
request(options, onResponseCallback);agent.createConnection(options, callback?): void<Object>net.createConnection()
了解选项的格式。对于自定义 agent,
此对象传递给自定义
createConnection
函数。<Function>createConnection
实现调用的函数,
特别是对于异步操作。<stream.Duplex><stream.Duplex>
创建的套接字。这是由默认
实现或自定义同步
createConnection
实现返回的。
如果自定义
createConnection
使用
callback
进行异步
操作,此返回值可能不是获取套接字的主要方式。产生一个用于 HTTP 请求的套接字/流。
默认情况下,此函数的行为与 net.createConnection() 完全相同,
同步返回创建的套接字。签名中的可选 callback 参数不被此默认实现使用。
然而,自定义 agent 可以重写此方法以提供更大的灵活性,
例如,异步创建套接字。当重写 createConnection 时:
- 同步套接字创建:重写的方法可以直接返回 套接字/流。
- 异步套接字创建:重写的方法可以接受
callback并将创建的套接字/流传递给它(例如,callback(null, newSocket))。 如果在套接字创建期间发生错误,应将其作为第一个 参数传递给callback(例如,callback(err))。
agent 将使用 options 和此内部 callback 调用提供的 createConnection 函数。
agent 提供的 callback 的签名为 (err, stream)。
agent.keepSocketAlive(socket): void<stream.Duplex>当 socket 从请求分离并可由
Agent 持久化时调用。默认行为是:
socket.setKeepAlive(true, this.keepAliveMsecs);
socket.unref();
return true;此方法可被特定的 Agent 子类重写。如果此
方法返回假值,套接字将被销毁而不是持久化
以供下一个请求使用。
socket 参数可以是 <net.Socket> 的实例,即
<stream.Duplex> 的子类。
agent.reuseSocket(socket, request): void<stream.Duplex><http.ClientRequest>当 socket 因 keep-alive 选项而被持久化后附加到 request 时调用。
默认行为是:
socket.ref();此方法可被特定的 Agent 子类重写。
socket 参数可以是 <net.Socket> 的实例,即
<stream.Duplex> 的子类。
agent.destroy(): void销毁 agent 当前使用的任何套接字。
通常不需要这样做。但是,如果使用启用了
keepAlive 的 agent,则最好在不再需要时显式关闭
agent。否则,
套接字可能会在服务器终止它们之前保持打开很长时间。
- 类型:
<Object>
当 keepAlive 启用时,包含 agent 当前等待使用的套接字数组的对象。
请勿修改。
freeSockets 列表中的套接字将在 'timeout' 时自动销毁并
从数组中移除。
agent.getName
History
The options parameter is now optional.
agent.getName(options?): void获取一组请求选项的唯一名称,以确定连接
是否可以复用。对于 HTTP agent,这将返回
host:port:localAddress 或 host:port:localAddress:family。对于 HTTPS agent,
名称包括 CA、cert、ciphers 和其他决定套接字可复用性的
HTTPS/TLS 特定选项。
- 类型:
<number>
默认设置为 256。对于启用了 keepAlive 的 agent,这
设置了将保持在空闲状态的最大套接字数。
- 类型:
<number>
默认设置为 Infinity。确定 agent
每个源可以打开多少个并发套接字。源是 agent.getName() 的返回值。
- 类型:
<number>
默认设置为 Infinity。确定 agent
可以打开多少个并发套接字。与 maxSockets 不同,此参数适用于所有源。
- 类型:
<Object>
包含尚未分配给 套接字的请求队列的对象。请勿修改。
- 类型:
<Object>
包含 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 设置为 true,Content-Length 头部值不匹配将导致抛出 Error,标识为 code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'。
Content-Length 值应为字节数,而非字符数。使用 Buffer.byteLength() 来确定主体的字节长度。
事件:'abort'
History
稳定性:0 - 已废弃。请改为监听
'close'事件。
当请求被客户端中止时触发。此事件仅在第一次调用 abort() 时触发。
事件:'close'
History
表示请求已完成,或其底层连接在响应完成之前被提前终止。
事件:'connect'
History
每当服务器响应带有 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
当服务器发送 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
<http.IncomingMessage>当收到此请求的响应时触发。此事件仅触发一次。
事件:'socket'
History
<stream.Duplex>除非用户指定了 <net.Socket> 以外的 socket 类型,否则保证此事件会传递一个 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类。
事件:'timeout'
History
当底层 socket 因无活动而超时时触发。这仅通知 socket 处于空闲状态。必须手动销毁请求。
事件:'upgrade'
History
每当服务器响应带有升级的请求时触发。如果没有监听此事件且响应状态码为 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);
});
});request.abort(): void稳定性:0 - 已废弃:请改用
request.destroy()。
将请求标记为中止。调用此方法将导致响应中的剩余数据被丢弃并且 socket 被销毁。
request.aborted
History
aborted 属性不再是一个时间戳数字。
稳定性:0 - 已废弃。请改用检查
request.destroyed。
- 类型:
<boolean>
如果请求已被中止,则 request.aborted 属性将为 true。
稳定性:0 - 已废弃。请使用
request.socket。
参见 request.socket。
request.cork(): void参见 writable.cork()。
request.end(data?, encoding?, callback?): void完成发送请求。如果主体的任何部分未发送,它将把它们冲刷到流中。如果请求是分块的,这将发送终止符 '0\r\n\r\n'。
如果指定了 data,则相当于调用 request.write(data, encoding) 后跟 request.end(callback)。
如果指定了 callback,它将在请求流完成时被调用。
request.destroy(error?): void销毁请求。可选地触发 'error' 事件,并触发 'close' 事件。调用此方法将导致响应中的剩余数据被丢弃并且 socket 被销毁。
- 类型:
<boolean>
在调用 request.destroy() 后为 true。
稳定性:0 - 已废弃。请使用
request.writableEnded。
- 类型:
<boolean>
如果调用了 request.end(),request.finished 属性将为 true。如果请求是通过 http.get() 发起的,request.end() 将被自动调用。
request.flushHeaders(): void冲刷请求头部。
出于效率原因,Node.js 通常缓冲请求头部,直到调用 request.end() 或写入第一块请求数据。然后它尝试将请求头部和数据打包到单个 TCP 数据包中。
这通常是理想的(它节省了一次 TCP 往返),但当第一块数据直到可能更晚的时候才发送时则不然。request.flushHeaders() 绕过优化并启动请求。
request.getHeader(name): void读取请求上的一个头部。名称不区分大小写。返回值的类型取决于提供给 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[] 类型request.getHeaderNames(): void- 返回:
<string[]>
返回一个包含当前传出头部唯一名称的数组。所有头部名称均为小写。
request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);
const headerNames = request.getHeaderNames();
// headerNames === ['foo', 'cookie']request.getHeaders(): void- 返回:
<Object>
返回当前传出头部的浅拷贝。由于使用了浅拷贝,数组值可能会被变更,而无需额外调用各种头部相关的 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'] }request.getRawHeaderNames(): void- 返回:
<string[]>
返回一个包含当前传出原始头部唯一名称的数组。头部名称返回时保留其设置的确切大小写形式。
request.setHeader('Foo', 'bar');
request.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = request.getRawHeaderNames();
// headerNames === ['Foo', 'Set-Cookie']request.hasHeader(name): void如果由 name 标识的头部当前已设置在传出头部中,则返回 true。头部名称匹配不区分大小写。
const hasContentType = request.hasHeader('content-type');- 类型:
<number>默认:2000
限制最大响应头部数量。如果设置为 0,则不应用限制。
- 类型:
<string>请求路径。
- 类型:
<string>请求方法。
- 类型:
<string>请求主机。
- 类型:
<string>请求协议。
request.removeHeader(name): void<string>移除已在头部对象中定义的头部。
request.removeHeader('Content-Type');- 类型:
<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();request.setHeader(name, value): void为头部对象设置单个头部值。如果此头部已存在于待发送的头部中,其值将被替换。此处使用字符串数组来发送多个具有相同名称的头部。非字符串值将未经修改地存储。因此,request.getHeader() 可能返回非字符串值。但是,非字符串值将被转换为字符串以便网络传输。
request.setHeader('Content-Type', 'application/json');或
request.setHeader('Cookie', ['type=ninja', 'language=javascript']);当值为字符串时,如果它包含 latin1 编码之外的字符,将抛出异常。
如果需要在值中传递 UTF-8 字符,请使用 RFC 8187 标准对值进行编码。
const filename = 'Rock 🎵.txt';
request.setHeader('Content-Disposition', `attachment; filename*=utf-8''${encodeURIComponent(filename)}`);request.setNoDelay(noDelay?): void<boolean>一旦 socket 被分配给此请求并连接,socket.setNoDelay() 将被调用。
request.setSocketKeepAlive(enable?, initialDelay?): void一旦 socket 被分配给此请求并连接,socket.setKeepAlive() 将被调用。
request.setTimeout(timeout, callback?): void<number><Function>'timeout'
事件。一旦 socket 被分配给此请求并连接,socket.setTimeout() 将被调用。
指向底层 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> 的子类。
request.uncork(): void- 类型:
<boolean>
在调用 request.end() 后为 true。此属性不指示数据是否已冲刷,为此请改用 request.writableFinished。
- 类型:
<boolean>
如果在 'finish' 事件触发之前,所有数据已冲刷到底层系统,则为 true。
request.write(chunk, encoding?, callback?): void发送一块主体数据。此方法可以调用多次。如果未设置 Content-Length,数据将自动以 HTTP 分块传输编码进行编码,以便服务器知道数据何时结束。将添加 Transfer-Encoding: chunked 头部。必须调用 request.end() 来完成发送请求。
encoding 参数是可选的,仅当 chunk 是字符串时适用。默认为 'utf8'。
callback 参数是可选的,当这块数据被冲刷时将被调用,但仅当这块数据非空时。
如果整个数据成功冲刷到内核缓冲区,则返回 true。如果全部或部分数据入队到用户内存,则返回 false。当缓冲区再次空闲时,将触发 'drain'。
当 write 函数使用空字符串或缓冲区调用时,它什么都不做并等待更多输入。
类:http.Server
History
- 继承自:
<net.Server>
事件:'checkContinue'
History
<http.IncomingMessage><http.ServerResponse>每当收到带有 HTTP Expect: 100-continue 的请求时发出。
如果没有监听此事件,服务器将自动响应
100 Continue(视情况而定)。
处理此事件涉及调用 response.writeContinue()(如果客户端应继续发送请求主体),或者生成适当的
HTTP 响应(例如 400 Bad Request)(如果客户端不应继续发送请求主体)。
当此事件被发出并处理后,'request' 事件将
不会被发出。
事件:'checkExpectation'
History
<http.IncomingMessage><http.ServerResponse>每当收到带有 HTTP Expect 头部的请求时发出,其中
值不是 100-continue。如果没有监听此事件,服务器将
自动响应 417 Expectation Failed(视情况而定)。
当此事件被发出并处理后,'request' 事件将
不会被发出。
<Error><stream.Duplex>如果客户端连接发出 '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' 事件发生时,没有 request 或 response
对象,因此任何发送的 HTTP 响应,包括响应头部和负载,
必须 直接写入 socket 对象。必须注意
确保响应是格式正确的 HTTP 响应消息。
err 是 Error 的实例,带有两个额外的列:
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
<http.IncomingMessage>'request'
事件中一样<stream.Duplex>每当客户端请求 HTTP CONNECT 方法时发出。如果没有监听此事件,
则请求 CONNECT 方法的客户端的
连接将被关闭。
除非用户指定了 <net.Socket> 以外的 socket 类型,否则此事件保证传递一个 <net.Socket> 类的实例,
它是 <stream.Duplex> 的子类。
发出此事件后,请求的 socket 将没有 'data'
事件监听器,这意味着需要绑定它以便处理
发送到该服务器上数据的数据。
事件:'connection'
History
<stream.Duplex>当建立新的 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
<http.IncomingMessage>'request'
事件中一样<stream.Duplex>当 socket 上的请求数量达到
server.maxRequestsPerSocket 的阈值时,服务器将丢弃新请求
并发出 'dropRequest' 事件,然后向客户端发送 503。
事件:'request'
History
<http.IncomingMessage><http.ServerResponse>每当有请求时发出。每个连接可能有多个请求 (在 HTTP Keep-Alive 连接的情况下)。
<http.IncomingMessage>'request'
事件中一样<stream.Duplex>每当客户端的 HTTP 升级请求被接受时发出。默认情况下
所有 HTTP 升级请求都被忽略(即只发出常规的 'request' 事件
,坚持正常的 HTTP 请求/响应流程),除非你
监听此事件,在这种情况下它们都被接受(即发出 'upgrade'
事件,未来的通信必须直接通过原始流处理)。你可以使用
服务器 shouldUpgradeCallback 选项更精确地控制此行为。
监听此事件是可选的,客户端不能坚持协议 更改。
如果升级被 shouldUpgradeCallback 接受但没有注册事件处理程序
,则 socket 将被销毁,导致客户端立即连接关闭。
在传入请求带有主体的罕见情况下,该主体将被
正常解析,与升级流分开,原始流数据将
仅在其完成后才开始。为了确保从流读取不会被
等待请求主体读取所阻塞,流上的任何读取将自动开始请求主体流动。如果你想读取
请求主体,请确保在开始从升级流读取之前这样做(即你附加了 'data' 监听器)。
流参数通常是请求使用的 <net.Socket> 实例,但在某些情况下(例如带有请求主体),它可能是双工
流。如果需要,你可以通过 request.socket 访问请求底层的原始连接
,除非用户指定了另一个 socket 类型,否则它保证是 <net.Socket> 的实例。
server.close(callback?): void<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);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);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);server.headersTimeout
History
默认值现在设置为 [server.requestTimeout][] 或 60000 之间的最小值。
- 类型:
<number>默认值:server.requestTimeout或60000之间的最小值。
限制解析器等待接收完整 HTTP 头部的时间量。
如果超时过期,服务器响应状态 408,而不 将请求转发给请求监听器,然后关闭连接。
必须将其设置为非零值(例如 120 秒),以便在服务器前面没有部署反向代理的情况下保护免受 潜在的拒绝服务攻击。
server.listen(): void启动 HTTP 服务器监听连接。
此方法与 net.Server 中的 server.listen() 相同。
- 类型:
<boolean>指示服务器是否正在监听连接。
- 类型:
<number>默认值:2000
限制最大传入头部计数。如果设置为 0,将不应用限制。
- 类型:
<number>默认值:300000
设置从客户端接收整个请求的超时值(毫秒)。
如果超时过期,服务器响应状态 408,而不 将请求转发给请求监听器,然后关闭连接。
必须将其设置为非零值(例如 120 秒),以便在服务器前面没有部署反向代理的情况下保护免受 潜在的拒绝服务攻击。
server.setTimeout(msecs?, callback?): void设置 socket 的超时值,如果发生超时,则在
Server 对象上发出 'timeout' 事件,并将
socket 作为参数传递。
如果 Server 对象上有 'timeout' 事件监听器,则它将
使用超时的 socket 作为参数被调用。
默认情况下,服务器不会使 socket 超时。但是,如果将回调
分配给服务器的 'timeout' 事件,则必须显式处理
超时。
- 类型:
<number>每个 socket 的请求数。 默认值: 0(无限制)
关闭 keep alive 连接之前 socket 可以处理的最大请求数。
值 0 将禁用限制。
当达到限制时,它将 Connection 头部值设置为 close,
但不会实际关闭连接,达到限制后发送的后续请求将获得 503 Service Unavailable 作为响应。
- 类型:
<number>超时时间(毫秒)。 默认值: 0(无超时)
在 socket 被假定超时之前的不活动毫秒数。
值 0 将禁用传入连接的超时行为。
socket 超时逻辑在连接时设置,因此更改此 值仅影响服务器的新连接,不影响任何现有连接。
- 类型:
<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 超时逻辑在连接时设置,因此更改此值仅 影响服务器的新连接,不影响任何现有连接。
- 类型:
<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
当响应已发送时触发。更具体地说,当响应头部和主体的最后一段已移交操作系统以便通过网络传输时,会触发此事件。这并不意味着客户端已经收到任何内容。
response.addTrailers(headers): void<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。
稳定性:0 - 已弃用。使用
response.socket。
参见 response.socket。
response.cork(): void参见 writable.cork()。
response.end(data?, encoding?, callback?): void此方法向服务器发出信号,表明所有响应头部和主体都已发送;服务器应认为此消息已完成。每个响应都必须调用 response.end() 方法。
如果指定了 data,其效果类似于调用 response.write(data, encoding) 后跟 response.end(callback)。
如果指定了 callback,它将在响应流完成时调用。
稳定性:0 - 已弃用。使用
response.writableEnded。
- 类型:
<boolean>
如果已调用 response.end(),则 response.finished 属性将为 true。
response.flushHeaders(): void刷新响应头部。另参见:request.flushHeaders()。
response.getHeader(name): void<string>读取已排队但尚未发送给客户端的头部。名称不区分大小写。返回值的类型取决于提供给 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[] 类型response.getHeaderNames(): void- 返回:
<string[]>
返回一个包含当前传出头部唯一名称的数组。所有头部名称均为小写。
response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie']response.getHeaders(): void- 返回:
<Object>
返回当前传出头部的浅拷贝。由于使用的是浅拷贝,数组值可以在不调用各种头部相关的 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): void如果由 name 标识的头部当前设置在传出头部中,则返回 true。头部名称匹配不区分大小写。
const hasContentType = response.hasHeader('content-type');- 类型:
<boolean>
布尔值(只读)。如果已发送头部则为 true,否则为 false。
response.removeHeader(name): void<string>移除排队等待隐式发送的头部。
response.removeHeader('Content-Encoding');对原始 HTTP request 对象的引用。
- 类型:
<boolean>
当为 true 时,如果头部中尚未存在 Date 头部,则会自动生成并在响应中发送 Date 头部。默认为 true。
这应仅用于测试;大多数 HTTP 响应都需要 Date 头部(详见 RFC 9110 Section 6.6.1)。
response.setHeader(name, value): void返回响应对象。
为隐式头部设置单个头部值。如果此头部已存在于待发送的头部中,其值将被替换。此处使用字符串数组来发送多个具有相同名称的头部。非字符串值将未经修改地存储。因此,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?): void将 Socket 的超时值设置为 msecs。如果提供了 callback,则它作为监听器添加到响应对象的 'timeout' 事件上。
如果未将 'timeout' 监听器添加到请求、响应或服务器,则套接字在超时时会被销毁。如果处理程序分配给了请求、响应或服务器的 'timeout' 事件,则必须显式处理超时的套接字。
对底层 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> 的子类。
- 类型:
<number>默认:200
当使用隐式头部(未显式调用 response.writeHead())时,此属性控制在刷新头部时发送给客户端的状态码。
response.statusCode = 404;在响应头部发送给客户端后,此属性指示发出的状态码。
- 类型:
<string>
当使用隐式头部(未显式调用 response.writeHead())时,此属性控制在刷新头部时发送给客户端的状态消息。如果此属性保持为 undefined,则将使用该状态码的标准消息。
response.statusMessage = 'Not found';在响应头部发送给客户端后,此属性指示发出的状态消息。
- 类型:
<boolean>默认:false
如果设置为 true,Node.js 将检查 Content-Length 头部值与主体大小(以字节为单位)是否相等。Content-Length 头部值不匹配将导致抛出 Error,标识为 code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'。
response.uncork(): void- 类型:
<boolean>
在调用 response.end() 之后为 true。此属性不指示数据是否已刷新,为此请使用 response.writableFinished。
- 类型:
<boolean>
如果所有数据都已刷新到底层系统,则在 'finish' 事件发出之前立即为 true。
response.write(chunk, encoding?, callback?): void如果调用了此方法且尚未调用 response.writeHead(),它将切换到隐式头部模式并刷新隐式头部。
这发送响应主体的一块。可以多次调用此方法以提供主体的连续部分。
如果在 createServer 中将 rejectNonStandardBodyWrites 设置为 true,则当请求方法或响应状态不支持内容时,不允许写入主体。如果尝试为 HEAD 请求写入主体或作为 204 或 304 响应的一部分写入主体,则会抛出代码为 ERR_HTTP_BODY_NOT_ALLOWED 的同步 Error。
chunk 可以是字符串或 buffer。如果 chunk 是字符串,则第二个参数指定如何将其编码为字节流。当这块数据被刷新时,将调用 callback。
这是原始 HTTP 主体,与可能使用的更高级的多部分主体编码无关。
第一次调用 response.write() 时,它将把缓冲的头部信息和第一块主体发送给客户端。第二次调用 response.write() 时,Node.js 假设数据将被流式传输,并单独发送新数据。也就是说,响应被缓冲到主体的第一块。
如果整个数据成功刷新到内核缓冲区,则返回 true。如果全部或部分数据排队在用户内存中,则返回 false。当缓冲区再次空闲时,将发出 'drain'。
response.writeContinue(): void向客户端发送 HTTP/1.1 100 Continue 消息,表示应发送请求主体。参见 Server 上的 'checkContinue' 事件。
response.writeEarlyHints(hints, callback?): void<Object><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向请求发送响应头。状态码是 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。
response.writeProcessing(): void向客户端发送 HTTP/1.1 102 Processing 消息,表示应发送请求主体。
类:http.IncomingMessage
History
传入数据被消费后,destroyed 值返回 true。
readableHighWaterMark 值与 socket 的值镜像一致。
IncomingMessage 对象由 http.Server 或 http.ClientRequest 创建,并分别作为第一个参数传递给 'request' 和 'response' 事件。它可用于访问响应状态、头部和数据。
与其 socket 值(<stream.Duplex> 的子类)不同,IncomingMessage 本身继承自 <stream.Readable> 并单独创建,用于解析和发出传入的 HTTP 头部和负载,因为底层 socket 可能在保持活动的情况下被多次重用。
事件:'aborted'
History
稳定性:0 - 已弃用。请改为监听
'close'事件。
当请求被中止时发出。
事件:'close'
History
close 事件现在在请求完成时发出,而不是在底层 socket 关闭时。
当请求完成时发出。
稳定性:0 - 已弃用。请检查
<stream.Readable>中的message.destroyed。
- 类型:
<boolean>
如果请求已被中止,message.aborted 属性将为 true。
- 类型:
<boolean>
如果完整的 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(
'消息仍在发送时连接被终止');
});
});稳定性:0 - 已弃用。使用
message.socket。
message.socket 的别名。
message.destroy(error?): void在接收 IncomingMessage 的 socket 上调用 destroy()。如果提供了 error,则在 socket 上发出 'error' 事件,并将 error 作为参数传递给该事件的任何监听器。
- 类型:
<Object>
请求/响应头部对象。
头部名称和值的键值对。头部名称为小写。
// 打印类似以下内容:
//
// { 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*' }
console.log(request.headers);原始头部中的重复项根据头部名称按以下方式处理:
age、authorization、content-length、content-type、etag、expires、from、host、if-modified-since、if-unmodified-since、last-modified、location、max-forwards、proxy-authorization、referer、retry-after、server或user-agent的重复项将被丢弃。 要允许上述列出的头部重复值被连接,请在http.request()和http.createServer()中使用joinDuplicateHeaders选项。有关更多信息,请参阅 RFC 9110 第 5.3 节。set-cookie始终是一个数组。重复项会被添加到数组中。- 对于重复的
cookie头部,值用;连接在一起。 - 对于所有其他头部,值用
,连接在一起。
- 类型:
<Object>
类似于 message.headers,但没有连接逻辑,且值始终是字符串数组,即使对于只接收一次的头部也是如此。
// 打印类似以下内容:
//
// { 'user-agent': ['curl/7.22.0'],
// host: ['127.0.0.1:8000'],
// accept: ['*/*'] }
console.log(request.headersDistinct);- 类型:
<string>
如果是服务器请求,则为客户端发送的 HTTP 版本。如果是客户端响应,则为所连接服务器的 HTTP 版本。
可能是 '1.1' 或 '1.0'。
此外,message.httpVersionMajor 是第一个整数,message.httpVersionMinor 是第二个整数。
- 类型:
<string>
仅对从 http.Server 获得的请求有效。
请求方法,字符串形式。只读。示例:'GET'、'DELETE'。
- 类型:
<string[]>
原始请求/响应头部列表,完全按照接收到的样子。
键和值在同一个列表中。它 不是 元组列表。因此,偶数偏移量是键值,奇数偏移量是关联值。
头部名称不大写,重复项不合并。
// 打印类似以下内容:
//
// [ 'user-agent',
// '这是无效的,因为只能有一个',
// 'User-Agent',
// 'curl/7.22.0',
// 'Host',
// '127.0.0.1:8000',
// 'ACCEPT',
// '*/*' ]
console.log(request.rawHeaders);- 类型:
<string[]>
原始请求/响应尾部键和值,完全按照接收到的样子。仅在 'end' 事件处填充。
message.setTimeout(msecs, callback?): void调用 message.socket.setTimeout(msecs, callback)。
与连接关联的 net.Socket 对象。
支持 HTTPS 时,使用 request.socket.getPeerCertificate() 获取客户端的身份验证详细信息。
除非用户指定了 <net.Socket> 以外的 socket 类型或在内部设为空,否则此属性保证是 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
- 类型:
<number>
仅对从 http.ClientRequest 获得的响应有效。
3 位 HTTP 响应状态码。例如 404。
- 类型:
<string>
仅对从 http.ClientRequest 获得的响应有效。
HTTP 响应状态消息(原因短语)。例如 OK 或 Internal Server Error。
- 类型:
<Object>
请求/响应尾部对象。仅在 'end' 事件处填充。
- 类型:
<Object>
类似于 message.trailers,但没有连接逻辑,且值始终是字符串数组,即使对于只接收一次的头部也是如此。
仅在 'end' 事件处填充。
- 类型:
<string>
仅对从 http.Server 获得的请求有效。
请求 URL 字符串。这仅包含实际 HTTP 请求中存在的 URL。例如以下请求:
GET /status?name=ryan HTTP/1.1
Accept: text/plain要将 URL 解析为其组成部分:
new URL(`http://${process.env.HOST ?? 'localhost'}${request.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.ClientRequest 和 http.ServerResponse 的父类。从 HTTP 事务参与者的角度来看,它是一个抽象的传出消息。
事件:'drain'
History
当消息的缓冲区再次空闲时发出。
事件:'finish'
History
当传输成功完成时发出。
事件:'prefinish'
History
在调用 outgoingMessage.end() 后发出。
发出事件时,所有数据都已处理完毕,但不一定完全刷新。
outgoingMessage.addTrailers(headers): void<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。
outgoingMessage.appendHeader(name, value): void将单个头部值附加到头部对象。
如果值是数组,则相当于多次调用此方法。
如果该头部之前没有值,则相当于调用 outgoingMessage.setHeader(name, value)。
根据创建客户端请求或服务器时 options.uniqueHeaders 的值,这将导致头部被发送多次,或者单次发送且值用 ; 连接。
outgoingMessage.connection
History
稳定性:0 - 已弃用:请改用
outgoingMessage.socket。
outgoingMessage.cork(): void参见 writable.cork()。
outgoingMessage.destroy(error?): void销毁消息。一旦 socket 与消息关联并连接,该 socket 也将被销毁。
outgoingMessage.end(chunk, encoding?, callback?): void完成传出消息。如果有任何主体部分未发送,它将把它们刷新到底层系统。如果消息是分块的,它将发送终止块 0\r\n\r\n,并发送尾部(如果有)。
如果指定了 chunk,则相当于调用 outgoingMessage.write(chunk, encoding),然后调用 outgoingMessage.end(callback)。
如果提供了 callback,它将在消息完成时调用(相当于 'finish' 事件的监听器)。
outgoingMessage.flushHeaders(): void刷新消息头部。
出于效率原因,Node.js 通常缓冲消息头部,直到调用 outgoingMessage.end() 或写入第一块消息数据。然后它尝试将头部和数据打包到单个 TCP 数据包中。
这通常是希望的(它节省了一次 TCP 往返),但当第一块数据直到可能更晚才发送时则不然。outgoingMessage.flushHeaders() 绕过优化并启动消息。
outgoingMessage.getHeader(name): void<string>获取给定名称的 HTTP 头部的值。如果未设置该头部,返回值将为 undefined。
outgoingMessage.getHeaderNames(): void- 返回:
<string[]>
返回一个包含当前传出头部唯一名称的数组。所有名称均为小写。
outgoingMessage.getHeaders(): void- 返回:
<Object>
返回当前传出头部的浅拷贝。由于使用的是浅拷贝,数组值可能会被修改,而无需额外调用各种头部相关的 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'] }outgoingMessage.hasHeader(name): void如果由 name 标识的头部当前已设置在传出头部中,则返回 true。头部名称不区分大小写。
const hasContentType = outgoingMessage.hasHeader('content-type');- 类型:
<boolean>
只读。如果已发送头部,则为 true,否则为 false。
outgoingMessage.pipe(): void覆盖从遗留 Stream 类(http.OutgoingMessage 的父类)继承的 stream.pipe() 方法。
调用此方法将抛出 Error,因为 outgoingMessage 是只写流。
outgoingMessage.removeHeader(name): void<string>移除排队等待隐式发送的头部。
outgoingMessage.removeHeader('Content-Encoding');outgoingMessage.setHeader(name, value): void设置单个头部值。如果该头部已存在于待发送头部中,其值将被替换。使用字符串数组发送多个同名的头部。
outgoingMessage.setHeaders(headers): void为隐式头部设置多个头部值。
headers 必须是 Headers 或 Map 的实例,
如果头部已存在于待发送头部中,
其值将被替换。
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');
});outgoingMessage.setTimeout(msecs, callback?): void一旦 socket 与消息关联并连接,
socket.setTimeout() 将被调用,msecs 作为第一个参数。
底层 socket 的引用。通常,用户不希望访问此属性。
调用 outgoingMessage.end() 后,此属性将被设为空。
outgoingMessage.uncork(): void- 类型:
<number>
outgoingMessage.cork() 被调用的次数。
- 类型:
<boolean>
如果已调用 outgoingMessage.end(),则为 true。此属性不指示数据是否已刷新。为此,请改用 message.writableFinished。
- 类型:
<boolean>
如果所有数据都已刷新到底层系统,则为 true。
- 类型:
<number>
如果已分配,则为底层 socket 的 highWaterMark。否则,为 writable.write() 开始返回 false 时的默认缓冲区级别(16384)。
- 类型:
<number>
缓冲字节的数量。
- 类型:
<boolean>
始终为 false。
outgoingMessage.write(chunk, encoding?, callback?): void发送一块主体。此方法可以调用多次。
仅当 chunk 为字符串时,encoding 参数才相关。默认为 'utf8'。
callback 参数是可选的,当这块数据被刷新时将调用它。
如果整个数据成功刷新到内核缓冲区,则返回 true。如果全部或部分数据排队在用户内存中,则返回 false。当缓冲区再次空闲时,将发出 'drain' 事件。
- 类型:
<string[]>
解析器支持的 HTTP 方法列表。
- 类型:
<Object>
所有标准 HTTP 响应状态码及其简短描述的集合。例如,http.STATUS_CODES[404] === 'Not Found'。
http.createServer
History
添加 optimizeEmptyRequests 选项。
现在支持 shouldUpgradeCallback 选项。
现在支持 highWaterMark 选项。
现在支持 requestTimeout、headersTimeout、keepAliveTimeout 和connectionsCheckingInterval 选项。
noDelay 选项现在默认为 true。
现在支持 noDelay、keepAlive 和 keepAliveInitialDelay选项。
现在支持 insecureHTTPParser 选项。
现在支持 maxHeaderSize 选项。
现在支持 options 参数。
http.createServer(options?, requestListener?): void<Object>30000
。server.headersTimeout
。
默认值:
60000
。<number>socket
的
readableHighWaterMark
和
writableHighWaterMark
。这会影响
IncomingMessage
和
ServerResponse
的
highWaterMark
属性。
默认值:
请参阅
stream.getDefaultHighWaterMark()
。<boolean><http.IncomingMessage>IncomingMessage
类。对于扩展原始
IncomingMessage
很有用。
默认值:
IncomingMessage
。<boolean><boolean>true
,它会在收到新的传入连接后立即在 socket 上启用 keep-alive 功能,
类似于在 [
socket.setKeepAlive([enable][, initialDelay])
][
socket.setKeepAlive(enable, initialDelay)
] 中所做的。
默认值:
false
。<number>0
。server.keepAliveTimeout
。
默认值:
5000
。<number>--max-http-header-size
的值,即请求头部的最大长度(字节)。
默认值:
16384 (16 KiB)。<boolean>true
,它会在收到新的传入连接后立即禁用 Nagle 算法的使用。
默认值:
true
。server.requestTimeout
。
默认值:
300000
。<boolean>true
,它强制服务器对任何缺少 Host 头部的 HTTP/1.1
请求消息响应 400 (Bad Request) 状态码
(根据规范强制要求)。
默认值:
true
。<http.ServerResponse>ServerResponse
类
。对于扩展原始
ServerResponse
很有用。
默认值:
ServerResponse
。<Function>'upgrade'
事件(或者如果没有注册监听器,它们的 socket 将被销毁),而被拒绝的升级将像任何非升级请求一样触发
'request'
事件。此选项默认为
() => server.listenerCount('upgrade') > 0
。<Array>;
连接。<boolean>true
,则在写入没有正文的 HTTP 响应时会抛出错误。
默认值:
false
。<boolean>true
,没有
Content-Length
或
Transfer-Encoding
头部(表示没有正文)的请求将使用已结束的正文流初始化,因此它们永远不会发出任何流事件
(如
'data'
或
'end'
)。你可以使用
req.readableEnded
来检测这种情况。
默认值:
false
。<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?): voidhttp.get(url, options?, callback?): void<Object>http.request()
相同的
options
,默认方法设置为 GET。<Function><http.ClientRequest>由于大多数请求都是没有正文的 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);- 类型:
<http.Agent>
Agent 的全局实例,用作所有 HTTP 客户端请求的默认值。与默认 Agent 配置不同的是,它启用了 keepAlive 且 timeout 为 5 秒。
- 类型:
<number>
只读属性,指定 HTTP 头部的最大允许大小(字节)。默认为 16 KiB。可使用 --max-http-header-size CLI 选项进行配置。
可以通过传递 maxHeaderSize 选项来覆盖服务器和客户端请求的此设置。
http.request(options, callback?): voidhttp.request(url, options?, callback?): void<Object><http.Agent>
|
<boolean>Agent
行为。可能的值:<string>'user:password'
),用于计算 Authorization 头部。<Function>agent
选项时,产生用于请求的套接字/流的函数。这可用于避免仅为了覆盖默认
createConnection
函数而创建自定义
Agent
类。详见
agent.createConnection()
。任何
Duplex
流都是有效的返回值。<number>Agent
则为
agent.defaultPort
,否则为
undefined
。<number>host
或
hostname
时使用的 IP 地址族。有效值为
4
或
6
。未指定时,将同时使用 IP v4 和 v6。message.rawHeaders
相同。<number>dns.lookup()
提示][]。<string>'localhost'
。<string><boolean><boolean><string><number><Function>dns.lookup()
。<number>--max-http-header-size
的值(服务器接收到的响应头部的最大长度,字节)。
默认:
16384 (16 KiB)。<string>'GET'
。<string>'/index.html?page=12'
。当请求路径包含非法字符时会抛出异常。目前,只有空格会被拒绝,但未来可能会改变。
默认:
'/'
。<number>defaultPort
则为
defaultPort
,否则为
80
。<string>'http:'
。<boolean>Connection
、
Content-Length
、
Transfer-Encoding
和
Host
。如果设置为
false
,则必须手动添加所有必要的头部。默认为
true
。<boolean>Host
头部。如果提供,此项将覆盖
setDefaultHeaders
。默认为
true
。<AbortSignal><string>host
或
port
之一,则不能使用此项,因为它们指定的是 TCP 套接字。<number><Array>;
连接。<Function>socket.connect() 中的 options 也受支持。
Node.js 维护每个服务器的多个连接以发出 HTTP 请求。此函数允许透明地发出请求。
url 可以是字符串或 URL 对象。如果 url 是字符串,它将使用 new URL() 自动解析。如果它是 URL 对象,它将自动转换为普通的 options 对象。
如果同时指定了 url 和 options,则对象会被合并,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对提供的 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 令牌 [""]'
}http.validateHeaderValue(name, value): void对提供的 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"]'
}http.setMaxIdleHTTPParsers(max): void<number>1000
。设置空闲 HTTP 解析器的最大数量。
http.setGlobalProxyFromEnv(proxyEnv?): void<Function>
一个函数,用于将原始 agent 和 dispatcher 设置恢复到此
http.setGlobalProxyFromEnv()
被调用之前的状态。动态重置全局配置,以便在运行时为 fetch() 和 http.request()/https.request() 启用内置代理支持,作为使用 --use-env-proxy 标志或 NODE_USE_ENV_PROXY 环境变量的替代方案。它也可用于覆盖从环境变量配置的设置。
由于此函数重置全局配置,任何之前配置的 http.globalAgent、https.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_PROXY或http_proxy:HTTP 请求的代理服务器 URL。如果两者都设置,http_proxy优先。HTTPS_PROXY或https_proxy:HTTPS 请求的代理服务器 URL。如果两者都设置,https_proxy优先。NO_PROXY或no_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 环境变量:
NODE_USE_ENV_PROXY=1 HTTP_PROXY=http://proxy.example.com:8080 NO_PROXY=localhost,127.0.0.1 node client.js或使用 --use-env-proxy 标志。
HTTP_PROXY=http://proxy.example.com:8080 NO_PROXY=localhost,127.0.0.1 node --use-env-proxy client.js要使用 process.env(http.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 });