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
<Object><boolean>Connection
头的
keep-alive
值混淆。使用 agent 时始终发送
Connection: keep-alive
头,除非显式指定了
Connection
头,或者当
keepAlive
和
maxSockets
选项分别设置为
false
和
Infinity
时,在这种情况下
将使用
Connection: close
。
默认值:
false
。<number>keepAlive
选项时,指定
TCP Keep-Alive 数据包的 [初始延迟][]。
当
keepAlive
选项为
false
或
undefined
时忽略。
默认值:
1000
。<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);new Agent(options?): void<Object><boolean>Connection
头的
keep-alive
值混淆。使用 agent 时始终发送
Connection: keep-alive
头,除非显式指定了
Connection
头,或者当
keepAlive
和
maxSockets
选项分别设置为
false
和
Infinity
时,在这种情况下
将使用
Connection: close
。
默认值:
false
。<number>keepAlive
选项时,指定
TCP Keep-Alive 数据包的 [初始延迟][]。
当
keepAlive
选项为
false
或
undefined
时忽略。
默认值:
1000
。<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(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('已连接!');
// 通过 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(`在主响应之前收到信息:${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('已升级!');
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 时销毁 socket;否则在可能的情况下将其返回到相应的 Agent 池。
- 类型:
<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(`你的 IP 地址是 ${ip},源端口是 ${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。如果 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' 事件。
也可以通过 request.socket 访问该 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 连接的情况下)。
事件:'upgrade'
History
请求正文不再以原始(未解析)形式暴露在 socket 参数上。相反,如果接收到了正文,stream 参数将是一个 duplex 流,它只会在请求正文之后发出 socket 内容,而解析后的请求正文数据将像普通服务器的 'request' 事件一样从 request 中发出。
现在是否触发此事件可以由 shouldUpgradeCallback 控制,如果没有事件处理器在监听,socket 将在升级时被销毁。
不再监听此事件时,客户端发送 Upgrade 头不会再导致 socket 被销毁。
<http.IncomingMessage>'request'
事件<stream.Duplex>每当接受客户端的 HTTP 升级请求时触发。默认情况下,
所有 HTTP 升级请求都会被忽略(即只触发常规的 'request' 事件,
保持正常的 HTTP 请求/响应流程),除非你
监听此事件,在这种情况下它们都会被接受(即触发 'upgrade'
事件,之后的通信必须直接通过原始流处理)。你可以使用
服务器的 shouldUpgradeCallback 选项更精确地控制此行为。
监听此事件是可选的,客户端不能强制协议 变更。
如果 shouldUpgradeCallback 接受升级但没有注册任何事件处理器,
则 socket 将被销毁,导致客户端立即关闭连接。
在极少数请求包含正文的情况下,该正文会被
正常解析,并与升级流分离,而原始流数据
只会在其完成后开始。为确保从流中读取不会因等待
请求正文读取而被阻塞,对流的任何读取都会自动开始流动请求正文。如果你想读取
请求正文,请务必在开始读取升级流之前完成它(即附加一个 'data' 监听器)。
stream 参数通常是请求所使用的 <net.Socket> 实例,但在某些情况下(例如带有请求正文时),它可能是一个 duplex
流。如有必要,你可以通过 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) 连接,包括 连接到此服务器且正在发送请求或等待响应的活动连接。此方法_不会_销毁升级到其他 协议的 socket,例如 WebSocket 或 HTTP/2。
这是强制关闭所有连接的一种方式,应谨慎使用。 每当与
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 在关闭 keep alive 连接之前可处理的最大请求数。
值为 0 将禁用此限制。
达到限制时,会将 Connection 头的值设置为 close,但不会真正关闭连接;在达到限制后发送的后续请求将收到 503 Service Unavailable 响应。
<number>socket 在被认为超时之前的不活动毫秒数。
值为 0 将禁用传入连接的超时行为。
socket 超时逻辑在连接时设置,因此更改此值只会 影响到服务器的新连接,而不会影响任何现有连接。
server.keepAliveTimeout
History
http.Server.keepAliveTimeout 的默认值已从 5 秒更改为 65 秒。
<number>65000
(65 秒)。服务器在完成写入最后一个响应后, 在销毁 socket 之前,需要等待额外传入数据的 毫秒数。
此超时值与
server.keepAliveTimeoutBuffer 选项结合使用,以确定实际的
socket 超时时间,计算方式为:
socketTimeout = keepAliveTimeout + keepAliveTimeoutBuffer
如果服务器在 keep-alive 超时触发之前收到新数据,它将重置常规的不活动超时,即 server.timeout。
值为 0 将禁用传入连接上的 keep-alive 超时行为。
值为 0 会使 HTTP 服务器的行为类似于 Node.js 8.0.0 之前的版本,
当时没有 keep-alive 超时。
socket 超时逻辑在连接时设置,因此更改此值只会 影响到服务器的新连接,而不会影响任何现有连接。
<number>1000
(1 秒)。添加到
server.keepAliveTimeout 的额外缓冲时间,用于延长内部
socket 超时。
此缓冲区通过略微增加
socket 超时时间,相对于声明的 keep-alive 超时时间,从而帮助减少连接重置(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(`您的 IP 地址是 ${ip},源端口是 ${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('早期提示消息已发送');
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.writeInformation(statusCode, headers?, callback?): void<number>response.writeHead()
相同的形式。<Function>向客户端发送任意的 HTTP/1.1 1xx 信息性响应。这是 response.writeContinue()、response.writeProcessing() 和 response.writeEarlyHints() 的通用等价形式,并且可以在最终响应之前调用多次。在最终响应头部已发送后(通过 response.writeHead() 或隐式头部发送),调用此方法将抛出 ERR_HTTP_HEADERS_SENT。
客户端通过 http.ClientRequest 上的 'information' 事件接收这些响应。
response.writeInformation(110, { 'X-Progress': '50%' });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)。
当底层 socket 关闭或请求被销毁时中止的 <AbortSignal>。该信号在首次访问时惰性创建——对于从未使用此属性的请求,不会分配 <AbortController>。
当客户端在请求中途断开连接时,这对于取消下游异步工作(例如数据库查询或 fetch 调用)非常有用。
import http from 'node:http';
http.createServer(async (req, res) => {
try {
const data = await fetch('https://example.com/api', { signal: req.signal });
res.end(JSON.stringify(await data.json()));
} catch (err) {
if (err.name === 'AbortError') return;
res.statusCode = 500;
res.end('Internal Server Error');
}
}).listen(3000);与连接关联的 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)``
History
<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 选项。
现在支持 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
,在收到新的传入连接后会立即在套接字上启用 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'
事件(如果没有注册监听器,则其套接字将被销毁),而被拒绝的升级将像任何非升级请求一样触发
'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'
)。<Function>agent
选项时,用于生成套接字/流供请求使用的函数。可用它来
避免仅仅为了覆盖默认的
createConnection
函数而创建自定义
Agent
类。更多
细节请参见
agent.createConnection()
。任何
Duplex
流都可以作为有效返回值。<number>Agent
,则为
agent.defaultPort
,否则为
undefined
。<number>host
或
hostname
时使用的 IP 地址族。有效值为
4
或
6
。如果未指定,将同时使用 IPv4 和
IPv6。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
,
则为其值,否则为
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 });