- assert断言
- async_hooks异步钩子
- async_hooks/context异步上下文
- buffer缓冲区
- C++插件
- C/C++插件(使用Node-API)
- C++嵌入器
- child_process子进程
- cluster集群
- CLI命令行
- console控制台
- Corepack核心包
- crypto加密
- crypto/webcrypto网络加密
- debugger调试器
- deprecation弃用
- dgram数据报
- diagnostics_channel诊断通道
- dns域名服务器
- domain域
- Error错误
- events事件触发器
- fs文件系统
- global全局变量
- http超文本传输协议
- http2超文本传输协议2.0
- https安全超文本传输协议
- inspector检查器
- Intl国际化
- module模块
- module/cjsCommonJS模块
- module/esmECMAScript模块
- module/package包模块
- net网络
- os操作系统
- path路径
- perf_hooks性能钩子
- policy安全策略
- process进程
- punycode域名代码
- querystring查询字符串
- readline逐行读取
- repl交互式解释器
- report诊断报告
- stream流
- stream/web网络流
- string_decoder字符串解码器
- test测试
- timers定时器
- tls安全传输层
- trace_events跟踪事件
- tty终端
- url网址
- util实用工具
- v8引擎
- vm虚拟机
- wasi网络汇编系统接口
- worker_threads工作线程
- zlib压缩
Node.js v18.6.0 文档
- Node.js 18.6.0
-
►
目录
- http 超文本传输协议
http.Agent
类http.ClientRequest
类'abort'
事件'close'
事件'connect'
事件'continue'
事件'finish'
事件'information'
事件'response'
事件'socket'
事件'timeout'
事件'upgrade'
事件request.abort()
request.aborted
request.connection
request.cork()
request.end([data[, encoding]][, callback])
request.destroy([error])
request.finished
request.flushHeaders()
request.getHeader(name)
request.getHeaderNames()
request.getHeaders()
request.getRawHeaderNames()
request.hasHeader(name)
request.maxHeadersCount
request.path
request.method
request.host
request.protocol
request.removeHeader(name)
request.reusedSocket
request.setHeader(name, value)
request.setNoDelay([noDelay])
request.setSocketKeepAlive([enable][, initialDelay])
request.setTimeout(timeout[, callback])
request.socket
request.uncork()
request.writableEnded
request.writableFinished
request.write(chunk[, encoding][, callback])
http.Server
类'checkContinue'
事件'checkExpectation'
事件'clientError'
事件'close'
事件'connect'
事件'connection'
事件'request'
事件'upgrade'
事件server.close([callback])
server.closeAllConnections()
server.closeIdleConnections()
server.headersTimeout
server.listen()
server.listening
server.maxHeadersCount
server.requestTimeout
server.setTimeout([msecs][, callback])
server.maxRequestsPerSocket
server.timeout
server.keepAliveTimeout
http.ServerResponse
类'close'
事件'finish'
事件response.addTrailers(headers)
response.connection
response.cork()
response.end([data[, encoding]][, callback])
response.finished
response.flushHeaders()
response.getHeader(name)
response.getHeaderNames()
response.getHeaders()
response.hasHeader(name)
response.headersSent
response.removeHeader(name)
response.req
response.sendDate
response.setHeader(name, value)
response.setTimeout(msecs[, callback])
response.socket
response.statusCode
response.statusMessage
response.uncork()
response.writableEnded
response.writableFinished
response.write(chunk[, encoding][, callback])
response.writeContinue()
response.writeHead(statusCode[, statusMessage][, headers])
response.writeProcessing()
http.IncomingMessage
类'aborted'
事件'close'
事件message.aborted
message.complete
message.connection
message.destroy([error])
message.headers
message.headersDistinct
message.httpVersion
message.method
message.rawHeaders
message.rawTrailers
message.setTimeout(msecs[, callback])
message.socket
message.statusCode
message.statusMessage
message.trailers
message.trailersDistinct
message.url
http.OutgoingMessage
类'drain'
事件'finish'
事件'prefinish'
事件outgoingMessage.addTrailers(headers)
outgoingMessage.appendHeader(name, value)
outgoingMessage.connection
outgoingMessage.cork()
outgoingMessage.destroy([error])
outgoingMessage.end(chunk[, encoding][, callback])
outgoingMessage.flushHeaders()
outgoingMessage.getHeader(name)
outgoingMessage.getHeaderNames()
outgoingMessage.getHeaders()
outgoingMessage.hasHeader(name)
outgoingMessage.headersSent
outgoingMessage.pipe()
outgoingMessage.removeHeader(name)
outgoingMessage.setHeader(name, value)
outgoingMessage.setTimeout(msesc[, callback])
outgoingMessage.socket
outgoingMessage.uncork()
outgoingMessage.writableCorked
outgoingMessage.writableEnded
outgoingMessage.writableFinished
outgoingMessage.writableHighWaterMark
outgoingMessage.writableLength
outgoingMessage.writableObjectMode
outgoingMessage.write(chunk[, encoding][, callback])
http.METHODS
http.STATUS_CODES
http.createServer([options][, requestListener])
http.get(options[, callback])
http.get(url[, options][, callback])
http.globalAgent
http.maxHeaderSize
http.request(options[, callback])
http.request(url[, options][, callback])
http.validateHeaderName(name)
http.validateHeaderValue(name, value)
- http 超文本传输协议
-
►
索引
- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS模块
- module/esm ECMAScript模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- policy 安全策略
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
- ► 其他版本
- 搜索
目录
- http 超文本传输协议
http.Agent
类http.ClientRequest
类'abort'
事件'close'
事件'connect'
事件'continue'
事件'finish'
事件'information'
事件'response'
事件'socket'
事件'timeout'
事件'upgrade'
事件request.abort()
request.aborted
request.connection
request.cork()
request.end([data[, encoding]][, callback])
request.destroy([error])
request.finished
request.flushHeaders()
request.getHeader(name)
request.getHeaderNames()
request.getHeaders()
request.getRawHeaderNames()
request.hasHeader(name)
request.maxHeadersCount
request.path
request.method
request.host
request.protocol
request.removeHeader(name)
request.reusedSocket
request.setHeader(name, value)
request.setNoDelay([noDelay])
request.setSocketKeepAlive([enable][, initialDelay])
request.setTimeout(timeout[, callback])
request.socket
request.uncork()
request.writableEnded
request.writableFinished
request.write(chunk[, encoding][, callback])
http.Server
类'checkContinue'
事件'checkExpectation'
事件'clientError'
事件'close'
事件'connect'
事件'connection'
事件'request'
事件'upgrade'
事件server.close([callback])
server.closeAllConnections()
server.closeIdleConnections()
server.headersTimeout
server.listen()
server.listening
server.maxHeadersCount
server.requestTimeout
server.setTimeout([msecs][, callback])
server.maxRequestsPerSocket
server.timeout
server.keepAliveTimeout
http.ServerResponse
类'close'
事件'finish'
事件response.addTrailers(headers)
response.connection
response.cork()
response.end([data[, encoding]][, callback])
response.finished
response.flushHeaders()
response.getHeader(name)
response.getHeaderNames()
response.getHeaders()
response.hasHeader(name)
response.headersSent
response.removeHeader(name)
response.req
response.sendDate
response.setHeader(name, value)
response.setTimeout(msecs[, callback])
response.socket
response.statusCode
response.statusMessage
response.uncork()
response.writableEnded
response.writableFinished
response.write(chunk[, encoding][, callback])
response.writeContinue()
response.writeHead(statusCode[, statusMessage][, headers])
response.writeProcessing()
http.IncomingMessage
类'aborted'
事件'close'
事件message.aborted
message.complete
message.connection
message.destroy([error])
message.headers
message.headersDistinct
message.httpVersion
message.method
message.rawHeaders
message.rawTrailers
message.setTimeout(msecs[, callback])
message.socket
message.statusCode
message.statusMessage
message.trailers
message.trailersDistinct
message.url
http.OutgoingMessage
类'drain'
事件'finish'
事件'prefinish'
事件outgoingMessage.addTrailers(headers)
outgoingMessage.appendHeader(name, value)
outgoingMessage.connection
outgoingMessage.cork()
outgoingMessage.destroy([error])
outgoingMessage.end(chunk[, encoding][, callback])
outgoingMessage.flushHeaders()
outgoingMessage.getHeader(name)
outgoingMessage.getHeaderNames()
outgoingMessage.getHeaders()
outgoingMessage.hasHeader(name)
outgoingMessage.headersSent
outgoingMessage.pipe()
outgoingMessage.removeHeader(name)
outgoingMessage.setHeader(name, value)
outgoingMessage.setTimeout(msesc[, callback])
outgoingMessage.socket
outgoingMessage.uncork()
outgoingMessage.writableCorked
outgoingMessage.writableEnded
outgoingMessage.writableFinished
outgoingMessage.writableHighWaterMark
outgoingMessage.writableLength
outgoingMessage.writableObjectMode
outgoingMessage.write(chunk[, encoding][, callback])
http.METHODS
http.STATUS_CODES
http.createServer([options][, requestListener])
http.get(options[, callback])
http.get(url[, options][, callback])
http.globalAgent
http.maxHeaderSize
http.request(options[, callback])
http.request(url[, options][, callback])
http.validateHeaderName(name)
http.validateHeaderValue(name, value)
http 超文本传输协议#
源代码: lib/http.js
要使用 HTTP 服务器和客户端,则必须 require('node:http')
。
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
类#
Agent
负责管理 HTTP 客户端连接的持久性和重用。
它维护一个给定主机和端口的待处理请求队列,为每个请求重用单个套接字连接,直到队列为空,此时套接字要么被销毁,要么放入池中,在那里它会被再次用于请求到相同的主机和端口。
是销毁还是池化取决于 keepAlive
选项。
池化的连接会为其启用 TCP Keep-Alive,但服务器可能仍会关闭空闲连接,在这种情况下,它们将从池中删除,并在为该主机和端口发出新的 HTTP 请求时建立新连接。
服务器也可能拒绝允许通过同一个连接的多个请求,在这种情况下,必须为每个请求重新建立连接,并且不能池化。
Agent
仍将向该服务器发出请求,但每个请求都将通过新连接发生。
当客户端或服务器关闭连接时,它会从池中删除。
池中任何未使用的套接字都将被取消引用,以免在没有未完成请求时保持 Node.js 进程运行。
(见 socket.unref()
)。
一个很好的做法是,当不再使用时则 destroy()
Agent
实例,因为未使用的套接字会消耗操作系统资源。
当套接字触发 'close'
事件或 'agentRemove'
事件时,则套接字将从代理中删除。
当打算让 HTTP 请求长时间打开而不将其保留在代理中时,可以执行类似以下的操作:
http.get(options, (res) => {
// 做些事情
}).on('socket', (socket) => {
socket.emit('agentRemove');
});
代理也可用于单个请求。
通过提供 {agent: false}
作为 http.get()
或 http.request()
函数的选项,则单次使用的具有默认选项的 Agent
将用于客户端连接。
agent:false
:
http.get({
hostname: 'localhost',
port: 80,
path: '/',
agent: false // 仅为这个请求创建新代理
}, (res) => {
// 使用响应做些事情
});
new Agent([options])
#
options
<Object> 要在代理上设置的可配置选项集。 可以有以下字段:keepAlive
<boolean> 即使没有未完成的请求,也要保留套接字,这样它们就可以用于未来的请求,而无需重新建立 TCP 连接。 不要与Connection
标头的keep-alive
值混淆。 使用代理时总是发送Connection: keep-alive
标头,除非显式指定了Connection
标头或当keepAlive
和maxSockets
选项分别设置为false
和Infinity
,在这种情况下将使用Connection: close
。 默认值:false
。keepAliveMsecs
<number> 使用keepAlive
选项时,指定 TCP Keep-Alive 数据包的初始延迟。 当keepAlive
选项为false
或undefined
时则忽略。 默认值:1000
。maxSockets
<number> 每个主机允许的最大套接字数量。 如果同一主机打开多个并发连接,则每个请求都将使用新的套接字,直到达到maxSockets
值。 如果主机尝试打开的连接数超过maxSockets
,则额外的请求将进入待处理请求队列,并在现有连接终止时进入活动连接状态。 这确保在任何时间点,给定的主机最多有maxSockets
个活动连接。 默认值:Infinity
。maxTotalSockets
<number> 所有主机总共允许的最大套接字数量。 每个请求将使用新的套接字,直到达到最大值。 默认值:Infinity
。maxFreeSockets
<number> 每台主机在空闲状态下保持打开的最大套接字数。 仅当keepAlive
设置为true
时才相关。 默认值:256
。scheduling
<string> 选择下一个要使用的空闲套接字时应用的调度策略。 它可以是'fifo'
或'lifo'
。 两种调度策略的主要区别在于'lifo'
选择最近使用的套接字,而'fifo'
选择最近最少使用的套接字。 在每秒请求率较低的情况下,'lifo'
调度将降低选择可能因不活动而被服务器关闭的套接字的风险。 在每秒请求率较高的情况下,'fifo'
调度将最大化打开套接字的数量,而'lifo'
调度将保持尽可能低。 默认值:'lifo'
。timeout
<number> 套接字超时(以毫秒为单位)。 这将在创建套接字时设置超时。
socket.connect()
中的 options
也受支持。
http.request()
使用的默认 http.globalAgent
将所有这些值设置为各自的默认值。
要配置其中任何一个,则必须创建自定义的 http.Agent
实例。
const http = require('node:http');
const keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);
agent.createConnection(options[, callback])
#
options
<Object> 包含连接详细信息的选项。 查看net.createConnection()
以获取选项的格式callback
<Function> 接收创建的套接字的回调函数- 返回: <stream.Duplex>
生成用于 HTTP 请求的套接字/流。
默认情况下,此函数与 net.createConnection()
相同。
但是,如果需要更大的灵活性,自定义代理可能会覆盖此方法。
可以通过以下两种方式之一提供套接字/流:通过从此函数返回套接字/流,或将套接字/流传给 callback
。
此方法保证返回 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定 <net.Socket> 以外的套接字类型。
callback
的参数为 (err, stream)
。
agent.keepSocketAlive(socket)
#
socket
<stream.Duplex>
当 socket
从请求中分离并且可以由 Agent
持久化时调用。
默认行为是:
socket.setKeepAlive(true, this.keepAliveMsecs);
socket.unref();
return true;
此方法可以被特定的 Agent
子类覆盖。
如果此方法返回假值,则套接字将被销毁,而不是将其持久化以供下一个请求使用。
socket
参数可以是 <net.Socket>(<stream.Duplex> 的子类)的实例。
agent.reuseSocket(socket, request)
#
socket
<stream.Duplex>request
<http.ClientRequest>
当 socket
由于保持活动选项而持久化后附加到 request
时调用。
默认行为是:
socket.ref();
此方法可以被特定的 Agent
子类覆盖。
socket
参数可以是 <net.Socket>(<stream.Duplex> 的子类)的实例。
agent.destroy()
#
销毁代理当前正在使用的所有套接字。
通常没有必要这样做。
但是,如果使用启用了 keepAlive
的代理,则最好在不再需要代理时显式关闭该代理。
否则,套接字可能会在服务器终止它们之前保持打开很长时间。
agent.freeSockets
#
当启用 keepAlive
时,包含当前等待代理使用的套接字数组的对象。
不要修改。
freeSockets
列表中的套接字将被自动销毁并从 'timeout'
上的数组中删除。
agent.getName([options])
#
获取一组请求选项的唯一名称,以确定是否可以重用连接。
对于 HTTP 代理,则这将返回 host:port:localAddress
或 host:port:localAddress:family
。
对于 HTTPS 代理,则名称包括 CA、证书、密码和其他确定套接字可重用性的 HTTPS/TLS 特定选项。
agent.maxFreeSockets
#
默认设置为 256。
对于启用了 keepAlive
的代理,这将设置在空闲状态下将保持打开的最大套接字数量。
agent.maxSockets
#
默认设置为 Infinity
。
确定代理可以为每个来源打开多少个并发套接字。
来源是 agent.getName()
的返回值。
agent.maxTotalSockets
#
默认设置为 Infinity
。
确定代理可以打开多少个并发套接字。
与 maxSockets
不同,此参数适用于所有来源。
agent.requests
#
包含尚未分配给套接字的请求队列的对象。 不要修改。
agent.sockets
#
包含代理当前正在使用的套接字数组的对象。 不要修改。
http.ClientRequest
类#
此对象从 http.request()
内部创建并返回。
它表示正在进行的请求,其标头已入队。
使用 setHeader(name, value)
、getHeader(name)
、removeHeader(name)
API 时,标头仍然是可变的。
实际标头将与第一个数据块一起发送或在调用 request.end()
时发送。
要获得响应,则将 'response'
的监听器添加到请求对象。
当接收到响应头时,则请求对象会触发 'response'
。
'response'
事件使用一个参数执行,该参数是 http.IncomingMessage
的实例。
在 'response'
事件期间,可以向响应对象添加监听器;特别是监听 'data'
事件。
如果没有添加 'response'
句柄,则响应将被完全丢弃。
但是,如果添加了 'response'
事件句柄,则必须消费响应对象中的数据,方法是在有 'readable'
事件时调用 response.read()
,或者添加 'data'
句柄,或者调用 .resume()
方法。
在数据被消费之前,不会触发 'end'
事件。
此外,在读取数据之前,其会消耗内存,最终可能导致进程内存不足的错误。
为了向后兼容,如果注册了 'error'
监听器,则 res
只会触发 'error'
。
Node.js 不会检查内容长度和已经传输的正文的长度是否相等。
'abort'
事件#
'close'
event 。当请求被客户端中止时触发。
此事件仅在第一次调用 abort()
时触发。
'close'
事件#
表示请求已完成,或者其底层连接提前终止(在响应完成之前)。
'connect'
事件#
response
<http.IncomingMessage>socket
<stream.Duplex>head
<Buffer>
每次服务器使用 CONNECT
方法响应请求时触发。
如果未监听此事件,则接收 CONNECT
方法的客户端将关闭其连接。
除非用户指定 <net.Socket> 以外的套接字类型,否则此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
演示如何监听 'connect'
事件的客户端和服务器对:
const http = require('node:http');
const net = require('node:net');
const { URL } = require('node:url');
// 创建 HTTP 隧道代理
const proxy = http.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 = net.connect(port || 80, hostname, () => {
clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
'Proxy-agent: Node.js-Proxy\r\n' +
'\r\n');
serverSocket.write(head);
serverSocket.pipe(clientSocket);
clientSocket.pipe(serverSocket);
});
});
// 现在代理正在运行
proxy.listen(1337, '127.0.0.1', () => {
// 向隧道代理发出请求
const options = {
port: 1337,
host: '127.0.0.1',
method: 'CONNECT',
path: 'www.google.com:80'
};
const req = http.request(options);
req.end();
req.on('connect', (res, socket, head) => {
console.log('got connected!');
// 通过 HTTP 隧道发出请求
socket.write('GET / HTTP/1.1\r\n' +
'Host: www.google.com:80\r\n' +
'Connection: close\r\n' +
'\r\n');
socket.on('data', (chunk) => {
console.log(chunk.toString());
});
socket.on('end', () => {
proxy.close();
});
});
});
'continue'
事件#
当服务器发送 '100 Continue' HTTP 响应时触发,通常是因为请求包含 'Expect: 100-continue'。 这是客户端应该发送请求正文的指令。
'finish'
事件#
当发送请求时触发。 更具体地说,当响应头和正文的最后一段已移交给操作系统以通过网络传输时,则将触发此事件。 这并不意味着服务器已经收到任何东西。
'information'
事件#
info
<Object>
当服务器发送 1xx 中间响应(不包括 101 升级)时触发。 此事件的监听器将接收一个对象,其中包含 HTTP 版本、状态码、状态消息、键值标头对象和带有原始标头名称及其各自值的数组。
const http = require('node:http');
const options = {
host: '127.0.0.1',
port: 8080,
path: '/length_request'
};
// 发出请求
const req = http.request(options);
req.end();
req.on('information', (info) => {
console.log(`Got information prior to main response: ${info.statusCode}`);
});
101 升级状态不会触发此事件,因为它们脱离了传统的 HTTP 请求/响应链,例如 Web 套接字、就地 TLS 升级或 HTTP 2.0。 要收到 101 升级通知,请改为监听 'upgrade'
事件。
'response'
事件#
response
<http.IncomingMessage>
当接收到对此请求的响应时触发。 此事件仅触发一次。
'socket'
事件#
socket
<stream.Duplex>
除非用户指定 <net.Socket> 以外的套接字类型,否则此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
'timeout'
事件#
当底层套接字因不活动而超时时触发。 这仅通知套接字已空闲。 必须手动销毁请求。
另见: request.setTimeout()
。
'upgrade'
事件#
response
<http.IncomingMessage>socket
<stream.Duplex>head
<Buffer>
每次服务器响应升级请求时触发。 如果未监听此事件且响应状态码为 101 Switching Protocols,则接收升级标头的客户端将关闭其连接。
除非用户指定 <net.Socket> 以外的套接字类型,否则此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
演示如何监听 'upgrade'
事件的客户端服务器对。
const http = require('node:http');
// 创建 HTTP 服务器
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('okay');
});
server.on('upgrade', (req, socket, head) => {
socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'\r\n');
socket.pipe(socket); // 回声
});
// 现在该服务器正在运行
server.listen(1337, '127.0.0.1', () => {
// 发出请求
const options = {
port: 1337,
host: '127.0.0.1',
headers: {
'Connection': 'Upgrade',
'Upgrade': 'websocket'
}
};
const req = http.request(options);
req.end();
req.on('upgrade', (res, socket, upgradeHead) => {
console.log('got upgraded!');
socket.end();
process.exit(0);
});
});
request.abort()
#
request.destroy()
。将请求标记为中止。 调用它会导致响应中的剩余数据被丢弃并销毁套接字。
request.aborted
#
request.destroyed
。如果请求已中止,则 request.aborted
属性将为 true
。
request.connection
#
request.socket
.参见 request.socket
。
request.cork()
#
参见 writable.cork()
。
request.end([data[, encoding]][, callback])
#
data
<string> | <Buffer>encoding
<string>callback
<Function>- 返回: <this>
完成发送请求。
如果正文的任何部分未发送,则会将它们刷新到流中。
如果请求被分块,则将发送终止的 '0\r\n\r\n'
。
如果指定了 data
,则相当于调用 request.write(data, encoding)
后跟 request.end(callback)
。
如果指定了 callback
,则将在请求流完成时调用。
request.destroy([error])
#
销毁请求。
可选地触发 'error'
事件,并发出 'close'
事件。
调用它会导致响应中的剩余数据被丢弃并销毁套接字。
有关详细信息,请参阅 writable.destroy()
。
request.destroyed
#
在调用 request.destroy()
之后是 true
。
有关详细信息,请参阅 writable.destroyed
。
request.finished
#
request.writableEnded
.如果 request.end()
已被调用,则 request.finished
属性将为 true
。
如果请求是通过 http.get()
发起的,则会自动调用 request.end()
。
request.flushHeaders()
#
刷新请求头。
出于效率原因,Node.js 通常会缓冲请求头,直到调用 request.end()
或写入第一块请求数据。
然后尝试将请求头和数据打包到单个 TCP 数据包中。
这通常是需要的(节省了 TCP 往返),但是当第一个数据直到可能很晚才发送时才需要。
request.flushHeaders()
绕过优化并启动请求。
request.getHeader(name)
#
读取请求的标头。
该名称不区分大小写。
返回值的类型取决于提供给 request.setHeader()
的参数。
request.setHeader('content-type', 'text/html');
request.setHeader('Content-Length', Buffer.byteLength(body));
request.setHeader('Cookie', ['type=ninja', 'language=javascript']);
const contentType = request.getHeader('Content-Type');
// 'contentType' 是 'text/html'
const contentLength = request.getHeader('Content-Length');
// 'contentLength' 是数字类型
const cookie = request.getHeader('Cookie');
// 'cookie' 是 string[] 类型
request.getHeaderNames()
#
- 返回: <string[]>
返回包含当前传出标头的唯一名称的数组。 所有标头名称均为小写。
request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);
const headerNames = request.getHeaderNames();
// headerNames === ['foo', 'Cookie']
request.getHeaders()
#
- 返回: <Object>
返回当前传出标头的浅拷贝。 由于使用了浅拷贝,因此无需额外调用各种与标头相关的 http 模块方法即可更改数组值。 返回对象的键是标头名称,值是相应的标头值。 所有标头名称均为小写。
response.getHeaders()
方法返回的对象通常不是从 JavaScript Object
继承的原型。
这意味着典型的 Object
方法,例如 obj.toString()
、obj.hasOwnProperty()
和其他方法未定义且无法工作。
request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);
const headers = response.getHeaders();
// headers === { foo: 'bar', 'cookie': ['foo=bar', 'bar=baz'] }
request.getRawHeaderNames()
#
- 返回: <string[]>
返回包含当前传出原始标头的唯一名称的数组。 标头名称返回并设置了它们的确切大小写。
request.setHeader('Foo', 'bar');
request.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = request.getRawHeaderNames();
// headerNames === ['Foo', 'Set-Cookie']
request.hasHeader(name)
#
如果 name
标识的标头当前设置在传出标头中,则返回 true
。
标头名称匹配不区分大小写。
const hasContentType = request.hasHeader('content-type');
request.maxHeadersCount
#
- <number> 默认值:
2000
限制最大响应头计数。 如果设置为 0,则不会应用任何限制。
request.path
#
- <string> 请求的路径。
request.method
#
- <string> 请求的方法。
request.host
#
- <string> 请求的主机。
request.protocol
#
- <string> 请求的协议。
request.removeHeader(name)
#
name
<string>
删除已定义到标头对象中的标头。
request.removeHeader('Content-Type');
request.reusedSocket
#
- <boolean> 请求是否通过重用的套接字发送。
当通过启用保持活动的代理发送请求时,可能会重用底层套接字。 但是如果服务器在不幸的时间关闭连接,客户端可能会遇到 'ECONNRESET' 错误。
const http = require('node:http');
// 服务器默认有 5 秒保持活动超时
http
.createServer((req, res) => {
res.write('hello\n');
res.end();
})
.listen(3000);
setInterval(() => {
// 调整保持活动代理
http.get('http://localhost:3000', { agent }, (res) => {
res.on('data', (data) => {
// 什么都不做
});
});
}, 5000); // 以 5 秒的间隔发送请求,因此很容易达到空闲超时
通过标记请求是否重用套接字,可以基于它进行自动错误重试。
const http = require('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)
#
为标头对象设置单个标头值。
如果该标头已经存在于待发送的标头中,则其值将被替换。
在此处使用字符串数组发送具有相同名称的多个标头。
非字符串值将不加修改地存储。
因此,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])
#
noDelay
<boolean>
一旦套接字被分配给这个请求并被连接,则 socket.setNoDelay()
将被调用。
request.setSocketKeepAlive([enable][, initialDelay])
#
一旦套接字被分配给这个请求并被连接,则 socket.setKeepAlive()
将被调用。
request.setTimeout(timeout[, callback])
#
timeout
<number> 请求超时前的毫秒数。callback
<Function> 发生超时时要调用的可选函数。 与绑定到'timeout'
事件相同。- 返回: <http.ClientRequest>
一旦套接字被分配给这个请求并被连接,则 socket.setTimeout()
将被调用。
request.socket
#
对底层套接字的引用。
通常用户不会想要访问这个属性。
特别是,由于协议解析器附加到套接字的方式,套接字将不会触发 'readable'
事件。
const http = require('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> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。
request.uncork()
#
request.writableEnded
#
在调用 request.end()
之后是 true
。
此属性不指示数据是否已刷新,为此则使用 request.writableFinished
代替。
request.writableFinished
#
如果所有数据都已在 'finish'
事件触发之前立即刷新到底层系统,则为 true
。
request.write(chunk[, encoding][, callback])
#
chunk
<string> | <Buffer>encoding
<string>callback
<Function>- 返回: <boolean>
发送一块正文。
此方法可以被多次调用。
如果没有设置 Content-Length
,则数据将自动使用 HTTP 分块传输编码进行编码,以便服务器知道数据何时结束。
Transfer-Encoding: chunked
标头会被添加。
需要调用 request.end()
来完成发送请求。
encoding
参数是可选的,仅当 chunk
是字符串时才适用。
默认为 'utf8'
。
callback
参数是可选的,将在刷新此数据块时调用,但前提是该块非空。
如果整个数据被成功刷新到内核缓冲区,则返回 true
。
如果所有或部分数据在用户内存中排队,则返回 false
。
当缓冲区再次空闲时,则将触发 'drain'
。
当使用空字符串或缓冲区调用 write
函数时,则什么都不做并等待更多输入。
http.Server
类#
- 继承自: <net.Server>
'checkContinue'
事件#
request
<http.IncomingMessage>response
<http.ServerResponse>
每次收到带有 HTTP Expect: 100-continue
的请求时触发。
如果未监听此事件,则服务器将根据需要自动响应 100 Continue
。
如果客户端应该继续发送请求正文,则处理此事件涉及调用 response.writeContinue()
,或者如果客户端不应该继续发送请求正文,则生成适当的 HTTP 响应(例如 400 Bad Request)。
处理和处理此事件时,不会触发 'request'
事件。
'checkExpectation'
事件#
request
<http.IncomingMessage>response
<http.ServerResponse>
每次收到带有 HTTP Expect
标头的请求时触发,其中值不是 100-continue
。
如果未监听此事件,则服务器将根据需要自动响应 417 Expectation Failed
。
处理和处理此事件时,不会触发 'request'
事件。
'clientError'
事件#
exception
<Error>socket
<stream.Duplex>
如果客户端连接触发 'error'
事件,则会在此处转发。
此事件的监听器负责关闭/销毁底层套接字。
例如,可能希望使用自定义 HTTP 响应更优雅地关闭套接字,而不是突然切断连接。
除非用户指定 <net.Socket> 以外的套接字类型,否则此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
默认行为是在 HPE_HEADER_OVERFLOW
错误的情况下尝试使用 HTTP '400 Bad Request' 或 HTTP '431 Request Header Fields Too Large' 关闭套接字。
如果套接字不可写或已经写入数据,则会立即被销毁。
socket
是错误源自的 net.Socket
对象。
const http = require('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
: 当前请求的原始数据包。
在某些情况下,客户端已经收到响应和/或套接字已经被销毁,例如 ECONNRESET
错误。
在尝试向套接字发送数据之前,最好检查它是否仍然可写。
server.on('clientError', (err, socket) => {
if (err.code === 'ECONNRESET' || !socket.writable) {
return;
}
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
'close'
事件#
服务器关闭时触发。
'connect'
事件#
request
<http.IncomingMessage> HTTP 请求的参数,如它在'request'
事件中socket
<stream.Duplex> 服务器和客户端之间的网络套接字head
<Buffer> 隧道流的第一个数据包(可能为空)
每次客户端请求 HTTP CONNECT
方法时触发。
如果未监听此事件,则请求 CONNECT
方法的客户端将关闭其连接。
除非用户指定 <net.Socket> 以外的套接字类型,否则此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
触发此事件后,请求的套接字将没有 'data'
事件监听器,这意味着需要绑定它才能处理发送到该套接字上的服务器的数据。
'connection'
事件#
socket
<stream.Duplex>
当建立新的 TCP 流时会触发此事件。
socket
通常是 net.Socket
类型的对象。
通常用户不会想访问这个事件。
特别是,由于协议解析器附加到套接字的方式,套接字将不会触发 'readable'
事件。
socket
也可以在 request.socket
上访问。
此事件也可以由用户显式发出,以将连接注入 HTTP 服务器。
在这种情况下,任何 Duplex
流都可以通过。
如果此处调用 socket.setTimeout()
,则当套接字已服务请求时(如果 server.keepAliveTimeout
非零)超时将替换为 server.keepAliveTimeout
。
除非用户指定 <net.Socket> 以外的套接字类型,否则此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
'request'
事件#
request
<http.IncomingMessage>response
<http.ServerResponse>
每次有请求时触发。 每个连接可能有多个请求(在 HTTP Keep-Alive 连接的情况下)。
'upgrade'
事件#
request
<http.IncomingMessage> HTTP 请求的参数,如它在'request'
事件中socket
<stream.Duplex> 服务器和客户端之间的网络套接字head
<Buffer> 升级流的第一个数据包(可能为空)
每次客户端请求 HTTP 升级时触发。 监听此事件是可选的,客户端不能坚持协议更改。
触发此事件后,请求的套接字将没有 'data'
事件监听器,这意味着需要绑定它才能处理发送到该套接字上的服务器的数据。
除非用户指定 <net.Socket> 以外的套接字类型,否则此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
server.close([callback])
#
callback
<Function>
停止服务器接受新连接。
参见 net.Server.close()
。
server.closeAllConnections()
#
关闭所有连接到此服务器的连接。
server.closeIdleConnections()
#
关闭连接到此服务器的所有未发送请求或等待响应的连接。
server.headersTimeout
#
- <number> 默认值:
60000
限制解析器等待接收完整 HTTP 标头的时间。
如果超时到期,则服务器以状态 408 响应而不将请求转发给请求监听器,然后关闭连接。
必须将其设置为非零值(例如 120 秒)以防止潜在的拒绝服务攻击,以防在部署服务器之前没有反向代理的情况下。
server.listen()
#
启动 HTTP 服务器监听连接。
此方法与 net.Server
中的 server.listen()
相同。
server.listening
#
- <boolean> 指示服务器是否正在监听连接。
server.maxHeadersCount
#
- <number> 默认值:
2000
限制最大传入标头计数。 如果设置为 0,则不会应用任何限制。
server.requestTimeout
#
- <number> 默认值:
300000
设置从客户端接收整个请求的超时值(以毫秒为单位)。
如果超时到期,则服务器以状态 408 响应而不将请求转发给请求监听器,然后关闭连接。
必须将其设置为非零值(例如 120 秒)以防止潜在的拒绝服务攻击,以防在部署服务器之前没有反向代理的情况下。
server.setTimeout([msecs][, callback])
#
msecs
<number> 默认值: 0(无超时)callback
<Function>- 返回: <http.Server>
设置套接字的超时值,并在服务器对象上触发 'timeout'
事件,如果发生超时,则将套接字作为参数传入。
如果 Server 对象上有 'timeout'
事件监听器,则将使用超时套接字作为参数调用它。
默认情况下,服务器不会超时套接字。
但是,如果将回调分配给服务器的 'timeout'
事件,则必须显式处理超时。
server.maxRequestsPerSocket
#
- <number> 每个套接字的请求数。 默认值: 0(无限制)
关闭保持活动的连接之前,套接字可以处理的最大请求数。
0
值将禁用限制。
当达到限制时,则它会将 Connection
标头值设置为 close
,但不会实际地关闭连接,达到限制后发送的后续请求将获得 503 Service Unavailable
作为响应。
server.timeout
#
- <number> 以毫秒为单位的超时时间。 默认值: 0(无超时)
假定套接字超时之前不活动的毫秒数。
值 0
将禁用传入连接的超时行为。
套接字超时逻辑是在连接上设置的,因此更改此值只会影响到服务器的新连接,而不会影响任何现有连接。
server.keepAliveTimeout
#
- <number> 以毫秒为单位的超时时间。 默认值:
5000
(5秒)
在完成写入最后一个响应之后,在套接字将被销毁之前,服务器需要等待额外传入数据的不活动毫秒数。
如果服务器在 keep-alive 超时触发之前收到新数据,则将重置常规的不活动超时,即 server.timeout
。
值 0
将禁用传入连接上的保持活动超时行为。
值 0
使 http 服务器的行为类似于 8.0.0 之前的 Node.js 版本,后者没有保持活动超时。
套接字超时逻辑是在连接上设置的,因此更改此值只会影响到服务器的新连接,而不会影响任何现有连接。
http.ServerResponse
类#
此对象由 HTTP 服务器内部创建,而不是由用户创建。
它作为第二个参数传给 'request'
事件。
'close'
事件#
表示响应已完成,或者其底层连接提前终止(在响应完成之前)。
'finish'
事件#
发送响应时触发。 更具体地说,当响应头和正文的最后一段已移交给操作系统以通过网络传输时,则将触发此事件。 这并不意味着客户端已收到任何东西。
response.addTrailers(headers)
#
headers
<Object>
此方法向响应添加 HTTP 尾随标头(标头,但位于消息末尾)。
只有在响应使用分块编码时才会触发尾标; 如果不是(例如,如果请求是 HTTP/1.0),则它们将被静默丢弃。
HTTP 要求发送 Trailer
标头以发出尾标,其值中包含标头字段列表。
例如,
response.writeHead(200, { 'Content-Type': 'text/plain',
'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });
response.end();
尝试设置包含无效字符的标头字段名称或值将导致抛出 TypeError
。
response.connection
#
response.socket
.参见 response.socket
。
response.cork()
#
参见 writable.cork()
。
response.end([data[, encoding]][, callback])
#
data
<string> | <Buffer>encoding
<string>callback
<Function>- 返回: <this>
此方法向服务器发出信号,表明所有响应头和正文都已发送;该服务器应认为此消息已完成。
response.end()
方法必须在每个响应上调用。
如果指定了 data
,则其效果类似于调用 response.write(data, encoding)
后跟 response.end(callback)
。
如果指定了 callback
,则将在响应流完成时调用。
response.finished
#
response.writableEnded
.如果 response.end()
已被调用,则 response.finished
属性将为 true
。
response.flushHeaders()
#
刷新响应头。
另见: request.flushHeaders()
。
response.getHeader(name)
#
读取已排队但未发送到客户端的标头。
该名称不区分大小写。
返回值的类型取决于提供给 response.setHeader()
的参数。
response.setHeader('Content-Type', 'text/html');
response.setHeader('Content-Length', Buffer.byteLength(body));
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
const contentType = response.getHeader('content-type');
// contentType 是 'text/html'
const contentLength = response.getHeader('Content-Length');
// contentLength 是数字类型
const setCookie = response.getHeader('set-cookie');
// setCookie 是 string[] 类型
response.getHeaderNames()
#
- 返回: <string[]>
返回包含当前传出标头的唯一名称的数组。 所有标头名称均为小写。
response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie']
response.getHeaders()
#
- 返回: <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)
#
如果 name
标识的标头当前设置在传出标头中,则返回 true
。
标头名称匹配不区分大小写。
const hasContentType = response.hasHeader('content-type');
response.headersSent
#
布尔值(只读)。 如果标头被发送,则为真,否则为假。
response.removeHeader(name)
#
name
<string>
删除排队等待隐式发送的标头。
response.removeHeader('Content-Encoding');
response.req
#
对原始的 HTTP request
对象的引用。
response.sendDate
#
如果为真,则 Date 标头将自动生成并在响应中发送,如果它尚未出现在标头中。 默认为真。
这应该仅在测试时禁用; HTTP 需要响应中的 Date 标头。
response.setHeader(name, value)
#
name
<string>value
<any>- 返回: <http.ServerResponse>
返回响应对象。
为隐式标头设置单个标头值。
如果该标头已经存在于待发送的标头中,则其值将被替换。
在此处使用字符串数组发送具有相同名称的多个标头。
非字符串值将不加修改地存储。
因此,response.getHeader()
可能返回非字符串值。
但是,非字符串值将转换为字符串以进行网络传输。
相同的响应对象返回给调用者,以启用调用链。
response.setHeader('Content-Type', 'text/html');
或者
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
尝试设置包含无效字符的标头字段名称或值将导致抛出 TypeError
。
当标头已使用 response.setHeader()
设置时,则它们将与任何传给 response.writeHead()
的标头合并,其中传给 response.writeHead()
的标头优先。
// 返回 content-type = text/plain
const server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
});
如果调用了 response.writeHead()
方法而该方法没有被调用,则会直接将提供的标头值写入网络通道,而不进行内部缓存,标头的 response.getHeader()
不会产生预期的结果。
如果希望在将来可能进行检索和修改时逐步填充标头,则使用 response.setHeader()
而不是 response.writeHead()
。
response.setTimeout(msecs[, callback])
#
msecs
<number>callback
<Function>- 返回: <http.ServerResponse>
将套接字的超时值设置为 msecs
。
如果提供了回调,则将其添加为响应对象上 'timeout'
事件的监听器。
如果没有向请求、响应或服务器添加 'timeout'
监听器,则套接字在超时时会被销毁。
如果将句柄分配给请求、响应或服务器的 'timeout'
事件,则必须显式处理超时套接字。
response.socket
#
对底层套接字的引用。
通常用户不会想要访问这个属性。
特别是,由于协议解析器附加到套接字的方式,套接字将不会触发 'readable'
事件。
在 response.end()
之后,该属性为空。
const http = require('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> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型。
response.statusCode
#
- <number> 默认值:
200
使用隐式标头(不显式调用 response.writeHead()
)时,此属性控制在标头刷新时将发送到客户端的状态码。
response.statusCode = 404;
响应头发送到客户端后,该属性表示发送出去的状态码。
response.statusMessage
#
当使用隐式标头(不显式调用 response.writeHead()
)时,此属性控制在标头刷新时将发送到客户端的状态消息。
如果保留为 undefined
,则将使用状态码的标准消息。
response.statusMessage = 'Not found';
响应头发送到客户端后,该属性表示发送出去的状态消息。
response.uncork()
#
response.writableEnded
#
在调用 response.end()
之后是 true
。
此属性不指示数据是否已刷新,为此则使用 response.writableFinished
代替。
response.writableFinished
#
如果所有数据都已在 'finish'
事件触发之前立即刷新到底层系统,则为 true
。
response.write(chunk[, encoding][, callback])
#
chunk
<string> | <Buffer>encoding
<string> 默认值:'utf8'
callback
<Function>- 返回: <boolean>
如果此方法被调用且 response.writeHead()
还没被调用,则会切换到隐式的标头模式并刷新隐式的标头。
这会发送一块响应正文。 可以多次调用此方法以提供正文的连续部分。
在 node:http
模块中,当请求是 HEAD 请求时,响应正文会被省略。
同样,204
和 304
响应不得包含消息正文。
chunk
可以是字符串或缓冲区。
如果 chunk
是字符串,则第二个参数指定如何将其编码为字节流。
当刷新数据块时将调用 callback
。
这是原始的 HTTP 正文,与可能使用的更高级别的多部分正文编码无关。
第一次调用 response.write()
时,它会将缓存的标头信息和正文的第一个块发送给客户端。
第二次调用 response.write()
时,Node.js 会假定数据将被流式传输,并单独发送新数据。
也就是说,响应被缓冲到正文的第一个块。
如果整个数据被成功刷新到内核缓冲区,则返回 true
。
如果所有或部分数据在用户内存中排队,则返回 false
。
当缓冲区再次空闲时,则将触发 'drain'
。
response.writeContinue()
#
向客户端发送 HTTP/1.1 100 Continue 消息,指示应发送请求正文。
请参阅 Server
上的 'checkContinue'
事件。
response.writeHead(statusCode[, statusMessage][, headers])
#
statusCode
<number>statusMessage
<string>headers
<Object> | <Array>- 返回: <http.ServerResponse>
向请求发送响应头。
状态码是 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()
#
向客户端发送 HTTP/1.1 102 Processing 消息,表示应发送请求正文。
http.IncomingMessage
类#
- 继承自: <stream.Readable>
IncomingMessage
对象由 http.Server
或 http.ClientRequest
创建,并分别作为第一个参数传给 'request'
和 'response'
事件。
它可用于访问响应状态、标头和数据。
不同于其 socket
的值是 <stream.Duplex> 的子类,IncomingMessage
本身继承了 <stream.Readable> 并被单独创建以解析和触发传入的 HTTP 标头和有效载荷,因为在保持活动的情况下底层套接字可能被多次重用。
'aborted'
事件#
'close'
event 。当请求被中止时触发。
'close'
事件#
当请求完成时触发。
message.aborted
#
如果请求已中止,则 message.aborted
属性将为 true
。
message.complete
#
如果已接收并成功解析完整的 HTTP 消息,则 message.complete
属性将为 true
。
此属性作为一种确定客户端或服务器是否在连接终止之前完全传输消息的方法特别有用:
const req = http.request({
host: '127.0.0.1',
port: 8080,
method: 'POST'
}, (res) => {
res.resume();
res.on('end', () => {
if (!res.complete)
console.error(
'The connection was terminated while the message was still being sent');
});
});
message.connection
#
message.socket
.message.socket
的别名。
message.destroy([error])
#
在接收到 IncomingMessage
的套接字上调用 destroy()
。
如果提供了 error
,则在套接字上触发 'error'
事件,并将 error
作为参数传给该事件的任何监听器。
message.headers
#
请求/响应头对象。
标头名称和值的键值对。 标头名称是小写的。
// 打印如下内容:
//
// { 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*' }
console.log(request.getHeaders());
原始标头中的重复项按以下方式处理,具体取决于标头名称:
- 重复的
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
被丢弃。 set-cookie
始终是数组。 重复项被添加到数组中。- 对于重复的
cookie
标头,值使用;
连接。 - 对于所有其他标头,值使用
,
连接。
message.headersDistinct
#
类似于 message.headers
,但没有连接逻辑,并且值始终是字符串数组,即使对于仅收到一次的标头也是如此。
// 打印如下内容:
//
// { 'user-agent': ['curl/7.22.0'],
// host: ['127.0.0.1:8000'],
// accept: ['*/*'] }
console.log(request.headersDistinct);
message.httpVersion
#
在服务器请求的情况下,客户端发送的 HTTP 版本。
在客户端响应的情况下,连接到服务器的 HTTP 版本。
可能是 '1.1'
或 '1.0'
。
message.httpVersionMajor
是第一个整数,message.httpVersionMinor
是第二个。
message.method
#
仅适用于从 http.Server
获得的请求。
请求方法作为字符串。
只读。
示例:'GET'
、'DELETE'
。
message.rawHeaders
#
原始请求/响应头完全按照收到的方式列出。
键和值在同一个列表中。 它不是元组列表。 因此,偶数偏移是键值,奇数偏移是关联的值。
标头名称不小写,重复项不合并。
// 打印如下内容:
//
// [ 'user-agent',
// 'this is invalid because there can be only one',
// 'User-Agent',
// 'curl/7.22.0',
// 'Host',
// '127.0.0.1:8000',
// 'ACCEPT',
// '*/*' ]
console.log(request.rawHeaders);
message.rawTrailers
#
原始请求/响应尾标的键和值与收到的完全一样。
仅在 'end'
事件中填充。
message.setTimeout(msecs[, callback])
#
msecs
<number>callback
<Function>- 返回: <http.IncomingMessage>
调用 message.socket.setTimeout(msecs, callback)
。
message.socket
#
与连接关联的 net.Socket
对象。
使用 HTTPS 支持,使用 request.socket.getPeerCertificate()
获取客户端的身份验证详细信息。
此属性保证是 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了 <net.Socket> 以外的套接字类型或内部为空。
message.statusCode
#
仅对从 http.ClientRequest
获得的响应有效。
3 位 HTTP 响应状态码。
例如 404
。
message.statusMessage
#
仅对从 http.ClientRequest
获得的响应有效。
HTTP 响应状态消息(原因短语)。
例如 OK
或 Internal Server Error
。
message.trailers
#
请求/响应尾标对象。
仅在 'end'
事件中填充。
message.trailersDistinct
#
类似于 message.trailers
,但没有连接逻辑,并且值始终是字符串数组,即使对于仅收到一次的标头也是如此。
仅在 'end'
事件中填充。
message.url
#
仅适用于从 http.Server
获得的请求。
请求的网址字符串。 这仅包含实际 HTTP 请求中存在的网址。 接受以下请求:
GET /status?name=ryan HTTP/1.1
Accept: text/plain
要将网址解析为它的部分:
new URL(request.url, `http://${request.getHeaders().host}`);
当 request.url
为 '/status?name=ryan'
且 request.getHeaders().host
为 'localhost:3000'
时:
$ node
> new URL(request.url, `http://${request.getHeaders().host}`)
URL {
href: 'http://localhost:3000/status?name=ryan',
origin: 'http://localhost:3000',
protocol: 'http:',
username: '',
password: '',
host: 'localhost:3000',
hostname: 'localhost',
port: '3000',
pathname: '/status',
search: '?name=ryan',
searchParams: URLSearchParams { 'name' => 'ryan' },
hash: ''
}
http.OutgoingMessage
类#
- 继承自: <Stream>
该类作为 http.ClientRequest
和 http.ServerResponse
的父类。
从 HTTP 事务的参与者的角度来看,这是抽象的传出消息。
'drain'
事件#
当消息的缓冲区再次空闲时触发。
'finish'
事件#
当传输成功完成时触发。
'prefinish'
事件#
调用 outgoingMessage.end()
后触发。
触发事件时,所有数据都已处理,但不一定完全刷新。
outgoingMessage.addTrailers(headers)
#
headers
<Object>
添加 HTTP 尾标(标头,但在消息末尾)到消息。
如果消息被分块编码,则仅块头将被触发。 如果没有,则块头将被默默丢弃。
HTTP 要求发送 Trailer
标头以发出块头,其值中包含标头字段名称列表,例如
message.writeHead(200, { 'Content-Type': 'text/plain',
'Trailer': 'Content-MD5' });
message.write(fileData);
message.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });
message.end();
尝试设置包含无效字符的标头字段名称或值将导致抛出 TypeError
。
outgoingMessage.appendHeader(name, value)
#
name
<string> 标头名称value
<string> | <string[]> 标头值- 返回: <this>
为标头对象附加单一个标头值。
如果值为数组,则相当于多次调用该方法。
如果标头没有先前的值,则这相当于调用 outgoingMessage.setHeader(name, value)
。
根据创建客户端请求或服务器时 options.uniqueHeaders
的值,这将导致标头多次发送或单次发送,并使用 ;
连接值。
outgoingMessage.connection
#
outgoingMessage.socket
。outgoingMessage.cork()
#
参见 writable.cork()
。
outgoingMessage.destroy([error])
#
销毁消息。 一旦套接字与消息关联并连接,则该套接字也将被销毁。
outgoingMessage.end(chunk[, encoding][, callback])
#
chunk
<string> | <Buffer>encoding
<string> 可选的,默认值:utf8
callback
<Function> 可选的- 返回: <this>
完成传出消息。
如果正文的任何部分未发送,则会将它们刷新到底层系统。
如果消息被分块,则它将发送终止块 0\r\n\r\n
,并发送块尾(如果有)。
如果指定了 chunk
,则相当于调用 outgoingMessage.write(chunk, encoding)
,后跟 outgoingMessage.end(callback)
。
如果提供了 callback
,则在消息结束时调用(相当于 'finish'
事件的监听器)。
outgoingMessage.flushHeaders()
#
刷新消息标头。
出于效率原因,Node.js 通常会缓冲消息头,直到调用 outgoingMessage.end()
或写入第一块消息数据。
然后它尝试将标头和数据打包到单个 TCP 数据包中。
通常是需要的(节省了 TCP 往返),但不是在第一个数据没有被发送的时候,直到可能很晚。
outgoingMessage.flushHeaders()
绕过优化并启动消息。
outgoingMessage.getHeader(name)
#
name
<string> 标头名称- 返回 <string> | <undefined>
获取具有给定名称的 HTTP 标头的值。
如果未设置该标头,则返回值为 undefined
。
outgoingMessage.getHeaderNames()
#
- 返回 <string[]>
返回包含当前传出标头的唯一名称的数组。 所有名称均为小写。
outgoingMessage.getHeaders()
#
- 返回: <Object>
返回当前传出标头的浅拷贝。 由于使用了浅拷贝,因此无需额外调用各种与标头相关的 HTTP 模块方法即可更改数组值。 返回对象的键是标头名称,值是相应的标头值。 所有标头名称均为小写。
outgoingMessage.getHeaders()
方法返回的对象不是原型继承自 JavaScript Object
。
这意味着 obj.toString()
、obj.hasOwnProperty()
等典型的 Object
方法没有定义,将不起作用。
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)
#
如果 name
标识的标头当前设置在传出标头中,则返回 true
。
标头名称不区分大小写。
const hasContentType = outgoingMessage.hasHeader('content-type');
outgoingMessage.headersSent
#
只读。
如果标头已发送,则为 true
,否则为 false
。
outgoingMessage.pipe()
#
覆盖继承自旧版的 Stream
类(http.OutgoingMessage
的父类)的 stream.pipe()
方法。
调用此方法将抛出 Error
,因为 outgoingMessage
是只写流。
outgoingMessage.removeHeader(name)
#
name
<string> 标头名称
删除排队等待隐式发送的标头。
outgoingMessage.removeHeader('Content-Encoding');
outgoingMessage.setHeader(name, value)
#
设置单个标头值。 如果待发送标头中已经存在该标头,则替换其值。 使用字符串数组发送多个同名标头。
outgoingMessage.setTimeout(msesc[, callback])
#
msesc
<number>callback
<Function> 发生超时时要调用的可选函数。 与绑定到timeout
事件相同。- 返回: <this>
一旦套接字与消息关联并连接,则 socket.setTimeout()
将被调用,msecs
作为第一个参数。
outgoingMessage.socket
#
对底层套接字的引用。 通常,用户不会希望访问此属性。
调用 outgoingMessage.end()
后,该属性将被清空。
outgoingMessage.uncork()
#
outgoingMessage.writableCorked
#
调用 outgoingMessage.cork()
的次数。
outgoingMessage.writableEnded
#
如果调用了 outgoingMessage.end()
,则为 true
。
该属性不表示数据是否被刷新。
为此目的,则改用 message.writableFinished
。
outgoingMessage.writableFinished
#
如果所有数据都已刷新到底层系统,则为 true
。
outgoingMessage.writableHighWaterMark
#
如果分配了底层套接字的 highWaterMark
。
否则,writable.write()
开始时的默认缓冲级别返回 false(16384
)。
outgoingMessage.writableLength
#
缓冲的字节数。
outgoingMessage.writableObjectMode
#
始终为 false
。
outgoingMessage.write(chunk[, encoding][, callback])
#
chunk
<string> | <Buffer>encoding
<string> 默认值:utf8
callback
<Function>- 返回 <boolean>
发送一块正文。 此方法可以被多次调用。
encoding
参数仅在 chunk
是字符串时才相关。
默认为 'utf8'
。
callback
参数是可选的,当此数据被刷新时将被调用。
如果整个数据被成功刷新到内核缓冲区,则返回 true
。
如果所有或部分数据在用户内存中排队,则返回 false
。
当缓冲区再次空闲时将触发 'drain'
事件。
http.METHODS
#
解析器支持的 HTTP 方法列表。
http.STATUS_CODES
#
所有标准 HTTP 响应状态代码的集合,以及每个的简短描述。
例如,http.STATUS_CODES[404] === 'Not Found'
。
http.createServer([options][, requestListener])
#
-
options
<Object>IncomingMessage
<http.IncomingMessage> 指定要使用的IncomingMessage
类。 用于扩展原始的IncomingMessage
。 默认值:IncomingMessage
。ServerResponse
<http.ServerResponse> 指定要使用的ServerResponse
类。 用于扩展原始的ServerResponse
。 默认值:ServerResponse
。requestTimeout
: 设置从客户端接收整个请求的超时值(以毫秒为单位)。 有关详细信息,请参阅server.requestTimeout
。 默认值:300000
。headersTimeout
: 设置从客户端接收完整 HTTP 标头的超时值,以毫秒为单位。 有关详细信息,请参阅server.headersTimeout
。 默认值:60000
。keepAliveTimeout
: 在完成写入最后一个响应之后,在套接字将被销毁之前,服务器需要等待额外传入数据的不活动毫秒数。 有关详细信息,请参阅server.keepAliveTimeout
。 默认值:5000
。connectionsCheckingInterval
: 以毫秒为单位设置间隔值,以检查不完整请求中的请求和标头超时。 默认值:30000
。insecureHTTPParser
<boolean> 使用不安全的 HTTP 解析器,当为true
时接受无效的 HTTP 标头。 应避免使用不安全的解析器。 有关详细信息,请参阅--insecure-http-parser
。 默认值:false
maxHeaderSize
<number> 可选地覆盖此服务器接收到的请求的--max-http-header-size
值,即请求头的最大长度(以字节为单位)。 默认值: 16384 (16 KiB)。noDelay
<boolean> 如果设置为true
,则它会在收到新的传入连接后立即禁用 Nagle 算法。 默认值:true
。keepAlive
<boolean> 如果设置为true
,则它会在收到新的传入连接后立即在套接字上启用保持活动功能,类似于在 [socket.setKeepAlive([enable][, initialDelay])
][socket.setKeepAlive(enable, initialDelay)
] 中所做的事情。 默认值:false
。keepAliveInitialDelay
<number> 如果设置为正数,则它会设置在空闲套接字上发送第一个保持活跃探测之前的初始延迟。 默认值:0
。uniqueHeaders
<Array> 只应发送一次的响应标头列表。 如果标头的值是数组,则子项将使用;
连接。
-
requestListener
<Function> -
返回: <http.Server>
返回 http.Server
的新实例。
requestListener
是自动添加到 'request'
事件的函数。
const http = require('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);
const http = require('node:http');
// 创建本地服务器来从其接收数据
const server = http.createServer();
// 监听请求事件
server.on('request', (request, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: 'Hello World!'
}));
});
server.listen(8000);
http.get(options[, callback])
#
http.get(url[, options][, callback])
#
url
<string> | <URL>options
<Object> 接受与http.request()
相同的options
,但method
始终设置为GET
。 从原型继承的属性将被忽略。callback
<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.globalAgent
#
Agent
的全局实例,用作所有 HTTP 客户端请求的默认值。
http.maxHeaderSize
#
只读属性,指定 HTTP 标头的最大允许大小(以字节为单位)。
默认为 16 KiB。
可使用 --max-http-header-size
命令行选项进行配置。
这可以通过传入 maxHeaderSize
选项为服务器和客户端请求覆盖。
http.request(options[, callback])
#
http.request(url[, options][, callback])
#
url
<string> | <URL>options
<Object>agent
<http.Agent> | <boolean> 控制Agent
的行为。 可能的值:undefined
(默认): 为此主机和端口使用http.globalAgent
。Agent
对象: 显式使用传入的Agent
。false
: 使用具有默认值的新Agent
。
auth
<string> 用于计算授权标头的基本身份验证 ('user:password'
)。createConnection
<Function> 当不使用agent
选项时,生成用于请求的套接字/流的函数。 这可用于避免创建自定义Agent
类只是为了覆盖默认的createConnection
函数。 有关详细信息,请参阅agent.createConnection()
。 任何Duplex
流都是有效的返回值。defaultPort
<number> 协议的默认端口。 默认值: 如果使用Agent
则为agent.defaultPort
,否则为undefined
。family
<number> 解析host
或hostname
时要使用的 IP 地址族。 有效值为4
或6
。 当未指定时,则将使用 IP v4 和 v6。headers
<Object> 包含请求头的对象。hints
<number> 可选的dns.lookup()
提示。host
<string> 要向其发出请求的服务器的域名或 IP 地址。 默认值:'localhost'
。hostname
<string>host
的别名。 为了支持url.parse()
,如果同时指定了host
和hostname
,则将使用hostname
。insecureHTTPParser
<boolean> 使用不安全的 HTTP 解析器,当为true
时接受无效的 HTTP 标头。 应避免使用不安全的解析器。 有关详细信息,请参阅--insecure-http-parser
。 默认值:false
localAddress
<string> 用于绑定网络连接的本地接口。localPort
<number> 连接的本地端口。lookup
<Function> 自定义查找函数。 默认值:dns.lookup()
.maxHeaderSize
<number> 对于从服务器接收到的响应,可选择覆盖--max-http-header-size
的值(响应标头的最大长度,以字节为单位)。 默认值: 16384 (16 KiB)。method
<string> 指定 HTTP 请求方法的字符串。 默认值:'GET'
。path
<string> 请求的路径。 应包括查询字符串(如果有)。 例如'/index.html?page=12'
。 当请求路径包含非法字符时抛出异常。 目前,只有空格被拒绝,但将来可能会改变。 默认值:'/'
。port
<number> 远程服务器的端口。 默认值: 如果有设置则为defaultPort
,否则为80
。protocol
<string> 要使用的协议。 默认值:'http:'
。setHost
<boolean>: 指定是否自动添加Host
标头。 默认为true
。signal
<AbortSignal>: 可用于中止正在进行的请求的中止信号。socketPath
<string> Unix 域套接字。 如果指定了host
或port
之一,则不能使用,因为它们指定了 TCP 套接字。timeout
<number>: 指定套接字超时的数值(以毫秒为单位)。 这将在连接套接字之前设置超时。uniqueHeaders
<Array> 只应发送一次的请求标头列表。 如果标头的值是数组,则子项将使用;
连接。
callback
<Function>- 返回: <http.ClientRequest>
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
对象。
const http = require('node:http');
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 节。 -
发送授权标头将覆盖使用
auth
选项来计算基本身份验证。
使用 URL
作为 options
的示例:
const options = new URL('http://abc:xyz@example.com');
const req = http.request(options, (res) => {
// ...
});
在成功的请求中,将按以下顺序触发以下事件:
'socket'
'response'
res
对象上的'data'
,任意次数(如果响应正文为空,则根本不会触发'data'
,例如,在大多数重定向中)res
对象上的'end'
'close'
在连接错误的情况下,将触发以下事件:
'socket'
'error'
'close'
在收到响应之前过早关闭连接的情况下,将按以下顺序触发以下事件:
'socket'
- 使用具有消息
'Error: socket hang up'
和代码'ECONNRESET'
的错误的'error'
'close'
在收到响应之后过早关闭连接的情况下,将按以下顺序触发以下事件:
'socket'
'response'
res
对象上的'data'
,任意次数
- (在此处关闭连接)
res
对象上的'aborted'
res
对象上的'error'
,使用具有消息'Error: aborted'
和代码'ECONNRESET'
的错误。'close'
res
对象上的'close'
如果在分配套接字之前调用 req.destroy()
,则将按以下顺序触发以下事件:
- (在此处调用
req.destroy()
) - 使用具有消息
'Error: socket hang up'
和代码'ECONNRESET'
的错误的'error'
'close'
如果在连接成功之前调用 req.destroy()
,则将按以下顺序触发以下事件:
'socket'
- (在此处调用
req.destroy()
) - 使用具有消息
'Error: socket hang up'
和代码'ECONNRESET'
的错误的'error'
'close'
如果在收到响应之后调用 req.destroy()
,则将按以下顺序触发以下事件:
'socket'
'response'
res
对象上的'data'
,任意次数
- (在此处调用
req.destroy()
) res
对象上的'aborted'
res
对象上的'error'
,使用具有消息'Error: aborted'
和代码'ECONNRESET'
的错误。'close'
res
对象上的'close'
如果在分配套接字之前调用 req.abort()
,则将按以下顺序触发以下事件:
- (在此处调用
req.abort()
) 'abort'
'close'
如果在连接成功之前调用 req.abort()
,则将按以下顺序触发以下事件:
'socket'
- (在此处调用
req.abort()
) 'abort'
- 使用具有消息
'Error: socket hang up'
和代码'ECONNRESET'
的错误的'error'
'close'
如果在收到响应之后调用 req.abort()
,则将按以下顺序触发以下事件:
'socket'
'response'
res
对象上的'data'
,任意次数
- (在此处调用
req.abort()
) 'abort'
res
对象上的'aborted'
res
对象上的'error'
,使用具有消息'Error: aborted'
和代码'ECONNRESET'
的错误。'close'
res
对象上的'close'
设置 timeout
选项或使用 setTimeout()
函数将不会中止请求或执行除添加 'timeout'
事件外的任何操作。
传入 AbortSignal
然后在相应的 AbortController
上调用 abort
,与在请求本身上调用 .destroy()
的行为相同。
http.validateHeaderName(name)
#
name
<string>
在调用 res.setHeader(name, value)
时对提供的 name
执行低层验证。
将非法值作为 name
传入将导致抛出 TypeError
,由 code: 'ERR_INVALID_HTTP_TOKEN'
标识。
在将标头传给 HTTP 请求或响应之前,不必使用此方法。 HTTP 模块将自动验证此类标头。 示例:
示例:
const { validateHeaderName } = require('node:http');
try {
validateHeaderName('');
} catch (err) {
err instanceof TypeError; // --> true
err.code; // --> 'ERR_INVALID_HTTP_TOKEN'
err.message; // --> 'Header name must be a valid HTTP token [""]'
}
http.validateHeaderValue(name, value)
#
在调用 res.setHeader(name, value)
时对提供的 value
执行低层验证。
将非法值作为 value
传入将导致抛出 TypeError
。
- 未定义值错误由
code: 'ERR_HTTP_INVALID_HEADER_VALUE'
标识。 - 无效值字符错误由
code: 'ERR_INVALID_CHAR'
标识。
在将标头传给 HTTP 请求或响应之前,不必使用此方法。 HTTP 模块将自动验证此类标头。
示例:
const { validateHeaderValue } = require('node:http');
try {
validateHeaderValue('x-my-header', undefined);
} catch (err) {
err instanceof TypeError; // --> true
err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'; // --> true
err.message; // --> 'Invalid value "undefined" for header "x-my-header"'
}
try {
validateHeaderValue('x-my-header', 'oʊmɪɡə');
} catch (err) {
err instanceof TypeError; // --> true
err.code === 'ERR_INVALID_CHAR'; // --> true
err.message; // --> 'Invalid character in header content ["x-my-header"]'
}