HTTP
源代码: lib/http.js
此模块包含客户端和服务器,可以通过 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
新增于: v0.3.4
Agent
负责管理 HTTP 客户端的连接持久性和重用。它为给定的主机和端口维护一个待处理请求队列,为每个请求重用单个套接字连接,直到队列为空,此时套接字将被销毁或放入池中以便再次用于对同一主机和端口的请求。它是否被销毁或放入池中取决于 keepAlive
选项。
池化连接已启用 TCP 保活,但服务器仍可能关闭空闲连接,在这种情况下,它们将从池中移除,当对该主机和端口发出新的 HTTP 请求时,将建立新的连接。服务器也可能拒绝允许在同一连接上进行多个请求,在这种情况下,必须为每个请求重新建立连接,并且无法将其放入池中。Agent
仍将向该服务器发出请求,但每个请求都将通过新的连接发生。
当连接被客户端或服务器关闭时,它将从池中移除。池中任何未使用的套接字都将被取消引用,以免在没有未完成请求时使 Node.js 进程保持运行。(参见 socket.unref()
)。
当不再使用 Agent
实例时,最好将其 destroy()
,因为未使用的套接字会消耗操作系统资源。
当套接字发出 'close'
事件或 'agentRemove'
事件时,套接字将从代理中移除。当打算长时间保持一个 HTTP 请求打开而又不将其保留在代理中时,可以执行以下操作:
http
.get(options, res => {
// 执行操作
})
.on('socket', socket => {
socket.emit('agentRemove')
})
代理也可以用于单个请求。通过为 http.get()
或 http.request()
函数提供 {agent: false}
作为选项,将为客户端连接使用具有默认选项的一次性使用 Agent
。
agent:false
:
http.get(
{
hostname: 'localhost',
port: 80,
path: '/',
agent: false, // 为此单个请求创建一个新的代理
},
res => {
// 使用响应执行操作
}
)
new Agent([options])
[历史]
版本 | 变更 |
---|---|
v15.6.0, v14.17.0 | 将默认调度策略从 fifo 更改为 lifo 。 |
v14.5.0, v12.20.0 | 添加 scheduling 选项来指定空闲套接字调度策略。 |
v14.5.0, v12.19.0 | 添加 maxTotalSockets 选项到 Agent 构造函数。 |
v0.3.4 | 在 v0.3.4 版本中添加 |
options
<对象> 用于设置 Agent 的一系列可配置选项。可以包含以下字段:keepAlive
<布尔值> 即使没有未完成的请求,也保持套接字连接,以便在将来无需重新建立 TCP 连接即可使用它们。不要与Connection
头部的keep-alive
值混淆。使用 Agent 时,始终发送Connection: keep-alive
头部,除非显式指定Connection
头部,或者keepAlive
和maxSockets
选项分别设置为false
和Infinity
,在这种情况下将使用Connection: close
。默认值:false
。keepAliveMsecs
<数字> 使用keepAlive
选项时,指定 TCP Keep-Alive 数据包的初始延迟。当keepAlive
选项为false
或undefined
时忽略。默认值:1000
。maxSockets
<数字> 每个主机允许的最大套接字数。如果同一主机打开多个并发连接,每个请求都将使用新的套接字,直到达到maxSockets
值。如果主机尝试打开比maxSockets
更多的连接,则其他请求将进入待处理请求队列,并在现有连接终止时进入活动连接状态。这确保了在任何时间点,来自给定主机的活动连接最多为maxSockets
个。默认值:Infinity
。maxTotalSockets
<数字> 所有主机总共允许的最大套接字数。每个请求都将使用新的套接字,直到达到最大值。默认值:Infinity
。maxFreeSockets
<数字> 每个主机最多可保留空闲状态的套接字数。仅当keepAlive
设置为true
时才相关。默认值:256
。scheduling
<字符串> 选择下一个空闲套接字时要应用的调度策略。它可以是'fifo'
或'lifo'
。两种调度策略的主要区别在于,'lifo'
选择最近使用的套接字,而'fifo'
选择最久未使用的套接字。如果每秒请求率较低,'lifo'
调度将降低选择可能因服务器不活动而关闭的套接字的风险。如果每秒请求率较高,'fifo'
调度将最大化打开的套接字数量,而'lifo'
调度将使其保持尽可能低。默认值:'lifo'
。timeout
<数字> 套接字超时(毫秒)。这将在创建套接字时设置超时。
options
也支持 socket.connect()
中的选项。
要配置任何这些选项,必须创建一个自定义的 http.Agent
实例。
import { Agent, request } from 'node:http'
const keepAliveAgent = new Agent({ keepAlive: true })
options.agent = keepAliveAgent
request(options, onResponseCallback)
const http = require('node:http')
const keepAliveAgent = new http.Agent({ keepAlive: true })
options.agent = keepAliveAgent
http.request(options, onResponseCallback)
agent.createConnection(options[, callback])
新增于:v0.11.4
options
<Object> 包含连接细节的选项。查看net.createConnection()
以了解选项的格式callback
<Function> 接收已创建套接字的回调函数- 返回值: <stream.Duplex>
生成一个用于 HTTP 请求的套接字/流。
默认情况下,此函数与 net.createConnection()
相同。但是,如果需要更大的灵活性,自定义代理可以覆盖此方法。
套接字/流可以通过两种方式之一提供:从此函数返回套接字/流,或将套接字/流传递给 callback
。
此方法保证返回 <net.Socket> 类的一个实例,它是 <stream.Duplex> 的子类,除非用户指定了除 <net.Socket> 之外的套接字类型。
callback
的签名为 (err, stream)
。
agent.keepSocketAlive(socket)
新增于:v8.1.0
socket
<stream.Duplex>
当 socket
从请求中分离并且可能被 Agent
持久化时调用。默认行为是:
socket.setKeepAlive(true, this.keepAliveMsecs)
socket.unref()
return true
此方法可以被特定的 Agent
子类重写。如果此方法返回一个假值,则套接字将被销毁,而不是将其持久化以用于下一个请求。
socket
参数可以是 <net.Socket> 的实例,也可以是 <stream.Duplex> 的子类。
agent.reuseSocket(socket, request)
新增于:v8.1.0
socket
<stream.Duplex>request
<http.ClientRequest>
当 socket
由于 keep-alive 选项而被持久化后附加到 request
时调用。默认行为是:
socket.ref()
此方法可以被特定的 Agent
子类重写。
socket
参数可以是 <net.Socket> 的实例,也可以是 <stream.Duplex> 的子类。
agent.destroy()
新增于:v0.11.4
销毁代理程序当前正在使用的任何套接字。
通常不需要这样做。但是,如果使用启用了 keepAlive
的代理程序,则最好在不再需要时显式关闭代理程序。否则,套接字可能在服务器终止它们之前保持打开状态很长时间。
agent.freeSockets
[历史记录]
版本 | 变更 |
---|---|
v16.0.0 | 该属性现在具有 null 原型。 |
v0.11.4 | 新增于:v0.11.4 |
一个对象,其中包含当启用 keepAlive
时代理程序当前正在等待使用的套接字数组。请勿修改。
freeSockets
列表中的套接字将在 'timeout'
时自动销毁并从数组中移除。
agent.getName([options])
[历史记录]
版本 | 变更 |
---|---|
v17.7.0, v16.15.0 | options 参数现在是可选的。 |
v0.11.4 | 新增于:v0.11.4 |
获取一组请求选项的唯一名称,以确定是否可以重用连接。对于 HTTP 代理,这将返回 host:port:localAddress
或 host:port:localAddress:family
。对于 HTTPS 代理,名称包括 CA、证书、密码和其他确定套接字可重用性的 HTTPS/TLS 特定选项。
agent.maxFreeSockets
新增于: v0.11.7
默认设置为 256。对于启用了 keepAlive
的代理,这将设置保持空闲状态的套接字最大数量。
agent.maxSockets
新增于: v0.3.6
默认设置为 Infinity
。确定代理每个来源可以打开多少个并发套接字。来源是 agent.getName()
返回的值。
agent.maxTotalSockets
新增于: v14.5.0, v12.19.0
默认设置为 Infinity
。确定代理可以打开多少个并发套接字。与 maxSockets
不同,此参数适用于所有来源。
agent.requests
[历史记录]
版本 | 变更 |
---|---|
v16.0.0 | 该属性现在具有 null 原型。 |
v0.5.9 | 新增于: v0.5.9 |
一个包含尚未分配给套接字的请求队列的对象。请勿修改。
agent.sockets
[历史]
版本 | 变更 |
---|---|
v16.0.0 | 该属性现在具有 null 原型。 |
v0.3.6 | 添加于:v0.3.6 |
一个包含代理当前正在使用的套接字数组的对象。请勿修改。
类:http.ClientRequest
添加于:v0.1.17
此对象在内部创建,并从 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'
新增于:v1.4.1
自 v17.0.0, v16.12.0 起已弃用
当请求被客户端中止时发出。此事件仅在第一次调用 abort()
时发出。
事件:'close'
新增于:v0.5.4
指示请求已完成,或其底层连接过早终止(在响应完成之前)。
事件:'connect'
新增于:v0.7.0
response
<http.IncomingMessage>socket
<stream.Duplex>head
<Buffer>
每次服务器使用 CONNECT
方法响应请求时发出。如果未监听此事件,则接收 CONNECT
方法的客户端的连接将被关闭。
保证此事件传递的是 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类,除非用户指定了 <net.Socket> 以外的套接字类型。
客户端和服务器对,演示如何监听 'connect'
事件:
import { createServer, request } from 'node:http'
import { connect } from 'node:net'
import { URL } from 'node:url'
// 创建一个 HTTP 隧道代理
const proxy = createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' })
res.end('okay')
})
proxy.on('connect', (req, clientSocket, head) => {
// 连接到源服务器
const { port, hostname } = new URL(`http://${req.url}`)
const serverSocket = connect(port || 80, hostname, () => {
clientSocket.write('HTTP/1.1 200 Connection Established\r\n' + 'Proxy-agent: Node.js-Proxy\r\n' + '\r\n')
serverSocket.write(head)
serverSocket.pipe(clientSocket)
clientSocket.pipe(serverSocket)
})
})
// 现在代理正在运行
proxy.listen(1337, '127.0.0.1', () => {
// 向隧道代理发出请求
const options = {
port: 1337,
host: '127.0.0.1',
method: 'CONNECT',
path: 'www.google.com:80',
}
const req = request(options)
req.end()
req.on('connect', (res, socket, head) => {
console.log('got connected!')
// 通过 HTTP 隧道发出请求
socket.write('GET / HTTP/1.1\r\n' + 'Host: www.google.com:80\r\n' + 'Connection: close\r\n' + '\r\n')
socket.on('data', chunk => {
console.log(chunk.toString())
})
socket.on('end', () => {
proxy.close()
})
})
})
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'
新增于: v0.3.2
当服务器发送 '100 Continue' HTTP 响应时发出,通常是因为请求包含 'Expect: 100-continue'。这是一个指示客户端应该发送请求正文的指令。
事件: 'finish'
新增于: v0.3.6
当请求已发送时发出。更具体地说,当响应头和正文的最后一部分已移交给操作系统以通过网络传输时,就会发出此事件。它并不意味着服务器已经接收到了任何内容。
事件: 'information'
新增于: v10.0.0
info
<对象>
当服务器发送 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}`)
})
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(`在主响应之前获取信息: ${info.statusCode}`)
})
由于 101 Upgrade 状态与其传统 HTTP 请求/响应链(例如 WebSockets、就地 TLS 升级或 HTTP 2.0)的断开,因此不会触发此事件。要接收 101 Upgrade 通知,请改为侦听 'upgrade'
事件。
事件: 'response'
添加于: v0.1.0
response
<http.IncomingMessage>
当接收到此请求的响应时发出。此事件仅发出一次。
事件: 'socket'
添加于: v0.5.3
socket
<stream.Duplex>
此事件保证会传递 <net.Socket> 类的一个实例,它是 <stream.Duplex> 的子类,除非用户指定了 <net.Socket> 以外的套接字类型。
事件: 'timeout'
添加于: v0.7.8
当底层套接字由于空闲超时时发出。这只会通知套接字处于空闲状态。请求必须手动销毁。
事件: 'upgrade'
添加于: v0.1.94
response
<http.IncomingMessage>socket
<stream.Duplex>head
<Buffer>
每次服务器使用升级响应请求时发出。如果未侦听此事件且响应状态代码为 101 Switching Protocols,则接收升级标头的客户端的连接将被关闭。
此事件保证会传递 <net.Socket> 类的一个实例,它是 <stream.Duplex> 的子类,除非用户指定了 <net.Socket> 以外的套接字类型。
客户端服务器对,演示如何侦听 '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, 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)
})
})
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()
新增于: v0.3.8
自 v14.1.0, v13.14.0 起已弃用
[稳定性: 0 - 已弃用]
稳定性: 0 稳定性: 0 - 已弃用: 请改用 request.destroy()
。
将请求标记为已中止。调用此方法将导致响应中剩余的数据被丢弃,并销毁套接字。
request.aborted
[历史记录]
版本 | 变更 |
---|---|
v17.0.0, v16.12.0 | 自 v17.0.0, v16.12.0 起已弃用 |
v11.0.0 | aborted 属性不再是时间戳数字。 |
v0.11.14 | 新增于: v0.11.14 |
[稳定性: 0 - 已弃用]
稳定性: 0 稳定性: 0 - 已弃用。请改用 request.destroyed
。
如果请求已被中止,则 request.aborted
属性将为 true
。
request.connection
新增于:v0.3.0
自 v13.0.0 起已弃用
[稳定性:0 - 已弃用]
稳定性:0 稳定性:0 - 已弃用。请使用 request.socket
。
参见 request.socket
。
request.cork()
新增于:v13.2.0, v12.16.0
参见 writable.cork()
。
request.end([data[, encoding]][, callback])
[历史记录]
版本 | 变更 |
---|---|
v15.0.0 | data 参数现在可以是 Uint8Array 。 |
v10.0.0 | 此方法现在返回对 ClientRequest 的引用。 |
v0.1.90 | 新增于:v0.1.90 |
data
<string> | <Buffer> | <Uint8Array>encoding
<string>callback
<Function>- 返回值: <this>
结束发送请求。如果正文的任何部分未发送,它将把它们刷新到流中。如果请求是分块的,这将发送终止的 '0\r\n\r\n'
。
如果指定了 data
,则等效于调用 request.write(data, encoding)
然后调用 request.end(callback)
。
如果指定了 callback
,则在请求流完成时将调用它。
request.destroy([error])
[历史]
版本 | 变更 |
---|---|
v14.5.0 | 为与其他可读流保持一致,该函数返回 this 。 |
v0.3.0 | 新增于:v0.3.0 |
销毁请求。可以选择发出 'error'
事件,并发出 'close'
事件。调用此方法将导致响应中剩余的数据被丢弃,并且套接字被销毁。
更多详情请见 writable.destroy()
。
request.destroyed
新增于:v14.1.0, v13.14.0
在调用 request.destroy()
后为 true
。
更多详情请见 writable.destroyed
。
request.finished
新增于: v0.0.1
自 v13.4.0, v12.16.0 起已弃用
[稳定性: 0 - 已弃用]
稳定性: 0 稳定性: 0 - 已弃用。请使用 request.writableEnded
。
如果已调用 request.end()
,则 request.finished
属性将为 true
。如果请求是通过 http.get()
发起的,则会自动调用 request.end()
。
request.flushHeaders()
新增于: v1.6.0
刷新请求头。
出于效率原因,Node.js 通常会缓冲请求头,直到调用 request.end()
或写入请求数据的第一个块。然后它尝试将请求头和数据打包到单个 TCP 数据包中。
这通常是理想的(它节省了 TCP 往返),但当第一个数据可能要到很久以后才发送时则不然。request.flushHeaders()
会绕过此优化并启动请求。
request.getHeader(name)
新增于: v1.6.0
读取请求中的头部信息。名称大小写不敏感。返回值的类型取决于提供给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()
新增于: v7.7.0
- 返回值: <string[]>
返回一个数组,包含当前发出请求的头部信息的唯一名称。所有头部名称都为小写。
request.setHeader('Foo', 'bar')
request.setHeader('Cookie', ['foo=bar', 'bar=baz'])
const headerNames = request.getHeaderNames()
// headerNames === ['foo', 'cookie']
request.getHeaders()
新增于:v7.7.0
- 返回值: <Object>
返回当前输出报头的浅拷贝。由于使用了浅拷贝,因此可以在不额外调用各种与报头相关的 http 模块方法的情况下修改数组值。返回对象的键是报头名称,值是相应的报头值。所有报头名称都小写。
request.getHeaders()
方法返回的对象不原型继承自 JavaScript Object
。这意味着诸如 obj.toString()
、obj.hasOwnProperty()
等典型的 Object
方法未定义且将无法工作。
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()
新增于:v15.13.0, v14.17.0
- 返回值: <string[]>
返回一个数组,其中包含当前输出原始报头的唯一名称。报头名称以其设置的精确大小写返回。
request.setHeader('Foo', 'bar')
request.setHeader('Set-Cookie', ['foo=bar', 'bar=baz'])
const headerNames = request.getRawHeaderNames()
// headerNames === ['Foo', 'Set-Cookie']
request.hasHeader(name)
新增于: v7.7.0
如果名为 name
的头部目前已在发送的头部中设置,则返回 true
。头部名称匹配不区分大小写。
const hasContentType = request.hasHeader('content-type')
request.maxHeadersCount
- <number> 默认值:
2000
限制最大响应头部计数。如果设置为 0,则不应用任何限制。
request.path
新增于: v0.4.0
- <string> 请求路径。
request.method
新增于: v0.1.97
- <string> 请求方法。
request.host
新增于:v14.5.0, v12.19.0
- <string> 请求主机。
request.protocol
新增于:v14.5.0, v12.19.0
- <string> 请求协议。
request.removeHeader(name)
新增于:v1.6.0
name
<string>
移除 headers 对象中已定义的头信息。
request.removeHeader('Content-Type')
request.reusedSocket
新增于:v13.0.0, v12.16.0
- <boolean> 请求是否通过已重用的套接字发送。
当通过启用 keep-alive 的代理发送请求时,底层套接字可能会被重用。但是,如果服务器在不恰当的时间关闭连接,客户端可能会遇到 'ECONNRESET' 错误。
import http from 'node:http'
// 服务器默认有 5 秒的 keep-alive 超时时间
http
.createServer((req, res) => {
res.write('hello\n')
res.end()
})
.listen(3000)
setInterval(() => {
// 使用 keep-alive 代理
http.get('http://localhost:3000', { agent }, res => {
res.on('data', data => {
// 什么也不做
})
})
}, 5000) // 每 5 秒发送一次请求,以便更容易达到空闲超时
const http = require('node:http')
// 服务器默认有 5 秒的 keep-alive 超时时间
http
.createServer((req, res) => {
res.write('hello\n')
res.end()
})
.listen(3000)
setInterval(() => {
// 使用 keep-alive 代理
http.get('http://localhost:3000', { agent }, res => {
res.on('data', data => {
// 什么也不做
})
})
}, 5000) // 每 5 秒发送一次请求,以便更容易达到空闲超时
通过标记请求是否重用了套接字,我们可以基于此进行自动错误重试。
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()
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)
新增于: v1.6.0
为 headers 对象设置单个 header 值。如果此 header 已存在于待发送的 headers 中,则其值将被替换。在此处使用字符串数组来发送具有相同名称的多个 header。非字符串值将原样存储。因此,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])
新增于: v0.5.9
noDelay
<布尔值>
一旦将套接字分配给此请求并连接后,将调用 socket.setNoDelay()
。
request.setSocketKeepAlive([enable][, initialDelay])
新增于: v0.5.9
一旦将套接字分配给此请求并连接后,将调用 socket.setKeepAlive()
。
request.setTimeout(timeout[, callback])
[历史记录]
版本 | 变更 |
---|---|
v9.0.0 | 仅在套接字连接时一致设置套接字超时。 |
v0.5.9 | 新增于: v0.5.9 |
timeout
<数字> 请求超时之前的毫秒数。callback
<函数> 超时发生时调用的可选函数。与绑定到'timeout'
事件相同。- 返回值: <http.ClientRequest>
一旦将套接字分配给此请求并连接后,将调用 socket.setTimeout()
。
request.socket
新增于:v0.3.0
底层套接字的引用。通常用户不需要访问此属性。特别是,由于协议解析器连接到套接字的方式,套接字不会发出'readable'
事件。
import http from 'node:http'
const options = {
host: 'www.google.com',
}
const req = http.get(options)
req.end()
req.once('response', res => {
const ip = req.socket.localAddress
const port = req.socket.localPort
console.log(`Your IP address is ${ip} and your source port is ${port}.`)
// 消耗响应对象
})
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> 之外的套接字类型,否则此属性保证是 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类。
request.uncork()
新增于:v13.2.0, v12.16.0
request.writableEnded
新增于:v12.9.0
在调用 request.end()
之后为 true
。此属性不指示数据是否已刷新,为此请改用 request.writableFinished
。
request.writableFinished
新增于:v12.7.0
如果所有数据都已刷新到底层系统,则在发出 'finish'
事件之前立即为 true
。
request.write(chunk[, encoding][, callback])
[历史]
版本 | 变更 |
---|---|
v15.0.0 | chunk 参数现在可以是 Uint8Array 。 |
v0.1.29 | 新增于:v0.1.29 |
chunk
<string> | <Buffer> | <Uint8Array>encoding
<string>callback
<Function>- 返回值: <boolean>
发送正文的一部分数据。此方法可以多次调用。如果未设置 Content-Length
,则数据将自动使用 HTTP 分块传输编码进行编码,以便服务器知道数据何时结束。将添加 Transfer-Encoding: chunked
头。需要调用 request.end()
来完成发送请求。
encoding
参数是可选的,仅当 chunk
是字符串时才适用。默认为 'utf8'
。
callback
参数是可选的,当此块数据被刷新时将被调用,但只有当块非空时才会调用。
如果所有数据都成功刷新到内核缓冲区,则返回 true
。如果所有或部分数据排队在用户内存中,则返回 false
。缓冲区再次可用时将发出 'drain'
事件。
当 write
函数使用空字符串或缓冲区调用时,它什么也不做,并等待更多输入。
类: http.Server
新增于: v0.1.17
- 继承自: <net.Server>
事件: 'checkContinue'
新增于: v0.3.0
request
<http.IncomingMessage>response
<http.ServerResponse>
每次收到带有 HTTP Expect: 100-continue
请求头 的请求时发出。如果未监听此事件,服务器将自动根据情况响应 100 Continue
。
处理此事件涉及到如果客户端应该继续发送请求体则调用 response.writeContinue()
,或者如果客户端不应该继续发送请求体则生成合适的 HTTP 响应(例如 400 Bad Request)。
当此事件被发出并处理时,'request'
事件将不会被发出。
事件: 'checkExpectation'
新增于: v5.5.0
request
<http.IncomingMessage>response
<http.ServerResponse>
每次收到带有 HTTP Expect
请求头的请求时发出,其中值不是 100-continue
。如果未监听此事件,服务器将自动根据情况响应 417 Expectation Failed
。
当此事件被发出并处理时,'request'
事件将不会被发出。
事件:'clientError'
[历史]
版本 | 变更 |
---|---|
v12.0.0 | 如果发生 HPE_HEADER_OVERFLOW 错误,默认行为将返回 431 Request Header Fields Too Large。 |
v9.4.0 | rawPacket 是刚刚解析的当前缓冲区。将此缓冲区添加到 'clientError' 事件的错误对象中,以便开发人员可以记录损坏的数据包。 |
v6.0.0 | 如果为 'clientError' 附加了监听器,则将不再执行对 socket 调用 .destroy() 的默认操作。 |
v0.1.94 | v0.1.94 版本中添加 |
exception
<Error>socket
<stream.Duplex>
如果客户端连接发出 'error'
事件,它将被转发到这里。此事件的监听器负责关闭/销毁底层套接字。例如,人们可能希望使用自定义 HTTP 响应更优雅地关闭套接字,而不是突然断开连接。监听器结束前必须关闭或销毁套接字。
除非用户指定除 <net.Socket> 之外的套接字类型,否则保证此事件将传递 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
默认行为是尝试使用 HTTP '400 Bad Request' 关闭套接字,或者在 HPE_HEADER_OVERFLOW
错误的情况下使用 HTTP '431 Request Header Fields Too Large'。如果套接字不可写或当前附加的 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)
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'
新增于:v0.1.4
服务器关闭时发出。
事件:'connect'
新增于:v0.7.0
request
<http.IncomingMessage> HTTP 请求的参数,与'request'
事件中的参数相同socket
<stream.Duplex> 服务器和客户端之间的网络套接字head
<Buffer> 隧道流的第一个数据包(可能为空)
每次客户端请求 HTTP CONNECT
方法时发出。如果没有监听此事件,则请求 CONNECT
方法的客户端连接将被关闭。
保证此事件传递的是 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了除 <net.Socket> 之外的套接字类型。
发出此事件后,请求的套接字将没有 'data'
事件监听器,这意味着需要绑定它才能处理发送到该套接字上的服务器数据。
事件:'connection'
新增于:v0.1.0
socket
<stream.Duplex>
当建立新的 TCP 流时,会发出此事件。socket
通常是 net.Socket
类型的一个对象。通常用户不需要访问此事件。特别是,由于协议解析器附加到套接字的方式,套接字不会发出 'readable'
事件。socket
也可以在 request.socket
访问。
用户也可以显式发出此事件,以将连接注入 HTTP 服务器。在这种情况下,可以传递任何 Duplex
流。
如果在此处调用 socket.setTimeout()
,则当套接字已处理请求时(如果 server.keepAliveTimeout
非零),超时将被 server.keepAliveTimeout
替换。
此事件保证会传递 <net.Socket> 类的一个实例,它是 <stream.Duplex> 的子类,除非用户指定了 <net.Socket> 以外的套接字类型。
事件:'dropRequest'
新增于:v18.7.0, v16.17.0
request
<http.IncomingMessage> HTTP 请求的参数,与'request'
事件中的参数相同socket
<stream.Duplex> 服务器和客户端之间的网络套接字
当套接字上的请求数量达到 server.maxRequestsPerSocket
的阈值时,服务器将丢弃新的请求并发出 'dropRequest'
事件,然后向客户端发送 503
状态码。
事件:'request'
新增于:v0.1.0
request
<http.IncomingMessage>response
<http.ServerResponse>
每次有请求时都会发出此事件。每个连接可能有多个请求(对于 HTTP Keep-Alive 连接)。
事件:'upgrade'
[历史]
版本 | 变更 |
---|---|
v10.0.0 | 不再监听此事件不会导致套接字在客户端发送 Upgrade 头部时被销毁。 |
v0.1.94 | 新增于:v0.1.94 |
request
<http.IncomingMessage> HTTP 请求的参数,与'request'
事件中的参数相同socket
<stream.Duplex> 服务器和客户端之间的网络套接字head
<Buffer> 升级流的第一个数据包(可能为空)
每次客户端请求 HTTP 升级时都会发出此事件。监听此事件是可选的,客户端不能强制协议更改。
发出此事件后,请求的套接字将没有 'data'
事件监听器,这意味着需要绑定它才能处理发送到该套接字上的服务器的数据。
此事件保证会传递 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定了除 <net.Socket> 之外的套接字类型。
server.close([callback])
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 方法在返回之前关闭空闲连接。 |
v0.1.90 | 新增于:v0.1.90 |
callback
<函数>
停止服务器接受新连接并关闭连接到此服务器的所有连接,这些连接未发送请求或等待响应。参见 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()
新增于:v18.2.0
关闭连接到此服务器的所有已建立的 HTTP(S) 连接,包括正在发送请求或等待响应的活动连接。这不会销毁升级到其他协议(例如 WebSocket 或 HTTP/2)的套接字。
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()
新增于:v18.2.0
关闭所有连接到此服务器且未发送请求或等待响应的连接。
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
[历史]
版本 | 变更 |
---|---|
v19.4.0, v18.14.0 | 默认值现在设置为 60000 (60 秒) 或 requestTimeout 中较小的值。 |
v11.3.0, v10.14.0 | 新增于:v11.3.0, v10.14.0 |
- <数字> 默认值:
server.requestTimeout
或60000
中较小的值。
限制解析器等待接收完整 HTTP 头部的时长。
如果超时过期,服务器将返回状态码 408,而不会将请求转发到请求监听器,然后关闭连接。
为了防止在服务器未部署反向代理的情况下潜在的拒绝服务攻击,必须将其设置为非零值(例如 120 秒)。
server.listen()
启动 HTTP 服务器以监听连接。此方法与 net.Server
中的 server.listen()
方法相同。
server.listening
新增于:v5.7.0
- <boolean> 指示服务器是否正在监听连接。
server.maxHeadersCount
新增于:v0.7.0
- <number> 默认值:
2000
限制最大传入报头数量。如果设置为 0,则不应用任何限制。
server.requestTimeout
[历史记录]
版本 | 变更 |
---|---|
v18.0.0 | 默认请求超时时间从无超时更改为 300 秒(5 分钟)。 |
v14.11.0 | 新增于:v14.11.0 |
- <number> 默认值:
300000
设置从客户端接收整个请求的超时值(毫秒)。
如果超时过期,服务器将返回状态码 408,而不会将请求转发到请求侦听器,然后关闭连接。
必须将其设置为非零值(例如 120 秒),以防止在服务器未在前面部署反向代理的情况下发生潜在的拒绝服务攻击。
server.setTimeout([msecs][, callback])
[历史]
版本 | 变更 |
---|---|
v13.0.0 | 默认超时时间从 120 秒更改为 0(无超时)。 |
v0.9.12 | 新增于:v0.9.12 |
msecs
<数字> 默认值: 0(无超时)callback
<函数>- 返回值:<http.Server>
设置套接字的超时值,如果发生超时,则在 Server 对象上发出 'timeout'
事件,并将套接字作为参数传递。
如果 Server 对象上存在 'timeout'
事件监听器,则将使用超时的套接字作为参数调用它。
默认情况下,Server 不会使套接字超时。但是,如果将回调分配给 Server 的 'timeout'
事件,则必须显式处理超时。
server.maxRequestsPerSocket
新增于:v16.10.0
- <数字> 每个套接字的请求数。默认值: 0(无限制)
套接字在关闭保持活动连接之前可以处理的最大请求数。
值为 0
将禁用限制。
达到限制时,它会将 Connection
头的值设置为 close
,但不会实际关闭连接,达到限制后发送的后续请求将收到 503 Service Unavailable
作为响应。
server.timeout
[历史]
版本 | 变更 |
---|---|
v13.0.0 | 默认超时时间从 120s 变为 0 (无超时)。 |
v0.9.12 | 新增于:v0.9.12 |
- <数字> 超时时间(毫秒)。默认值: 0 (无超时)
套接字在被认为超时之前的不活动毫秒数。
值为 0
将禁用传入连接的超时行为。
套接字超时逻辑在连接时设置,因此更改此值仅影响服务器的新连接,而不影响任何现有连接。
server.keepAliveTimeout
新增于:v8.0.0
- <数字> 超时时间(毫秒)。默认值:
5000
(5 秒)。
服务器在完成上次响应写入后,需要等待更多传入数据的不活动毫秒数,之后套接字将被销毁。如果服务器在 keep-alive 超时触发之前收到新数据,它将重置常规不活动超时,即 server.timeout
。
值为 0
将禁用传入连接的 keep-alive 超时行为。值为 0
使 http 服务器的行为类似于 8.0.0 之前的 Node.js 版本,这些版本没有 keep-alive 超时。
套接字超时逻辑在连接时设置,因此更改此值仅影响服务器的新连接,而不影响任何现有连接。
server[Symbol.asyncDispose]()
新增于:v20.4.0
调用 server.close()
并返回一个 promise,该 promise 在服务器关闭时 fulfilled。
类:http.ServerResponse
新增于:v0.1.17
此对象由 HTTP 服务器内部创建,而非用户创建。它作为第二个参数传递给 'request'
事件。
事件:'close'
新增于:v0.6.7
指示响应已完成,或其底层连接过早终止(在响应完成之前)。
事件:'finish'
新增于:v0.3.6
当响应已发送时发出。更具体地说,当响应头和正文的最后一部分已传递给操作系统以通过网络传输时,就会发出此事件。它并不意味着客户端已经接收到了任何内容。
response.addTrailers(headers)
新增于:v0.3.0
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
新增于:v0.3.0
自 v13.0.0 起已弃用
[稳定性:0 - 已弃用]
稳定性:0 稳定性:0 - 已弃用。请使用 response.socket
。
参见 response.socket
。
response.cork()
新增于:v13.2.0, v12.16.0
参见 writable.cork()
。
response.end([data[, encoding]][, callback])
[历史]
版本 | 变更 |
---|---|
v15.0.0 | data 参数现在可以是 Uint8Array 。 |
v10.0.0 | 此方法现在返回 ServerResponse 的引用。 |
v0.1.90 | 新增于:v0.1.90 |
此方法向服务器发出信号,表明所有响应头和正文都已发送;服务器应将此消息视为已完成。必须对每个响应调用 response.end()
方法。
如果指定了 data
,其效果类似于调用 response.write(data, encoding)
然后调用 response.end(callback)
。
如果指定了 callback
,则在响应流完成时将调用它。
response.finished
新增于:v0.0.2
自 v13.4.0, v12.16.0 起已弃用
[稳定性:0 - 已弃用]
稳定性:0 稳定性:0 - 已弃用。请使用 response.writableEnded
。
如果已调用 response.end()
,则 response.finished
属性将为 true
。
response.flushHeaders()
新增于:v1.6.0
刷新响应头。另见:request.flushHeaders()
。
response.getHeader(name)
新增于:v0.4.0
读取已排队但尚未发送到客户端的标头。名称不区分大小写。返回值的类型取决于提供给 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()
新增于: v7.7.0
- 返回值: <string[]>
返回一个数组,包含当前输出报头的唯一名称。所有报头名称都为小写。
response.setHeader('Foo', 'bar')
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz'])
const headerNames = response.getHeaderNames()
// headerNames === ['foo', 'set-cookie']
response.getHeaders()
新增于: v7.7.0
- 返回值: <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)
新增于: v7.7.0
如果传出报头中当前已设置了由 name
标识的报头,则返回 true
。报头名称匹配不区分大小写。
const hasContentType = response.hasHeader('content-type')
response.headersSent
新增于: v0.9.3
布尔值(只读)。如果报头已发送,则为 true
,否则为 false
。
response.removeHeader(name)
新增于: v0.4.0
name
<string>
移除已排队等待隐式发送的报头。
response.removeHeader('Content-Encoding')
response.req
新增于: v15.7.0
对原始 HTTP request
对象的引用。
response.sendDate
新增于:v0.7.5
当值为 true
时,如果响应头中不存在 Date
头,则会自动生成并发送 Date
头。默认为 true
。
这应该只在测试时禁用;HTTP 协议要求响应中包含 Date
头。
response.setHeader(name, value)
新增于:v0.4.0
name
<字符串>value
<任意值>- 返回值:<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])
新增于: v0.9.12
msecs
<number>callback
<Function>- 返回值: <http.ServerResponse>
将 Socket 的超时值设置为 msecs
。如果提供了回调函数,则将其添加到响应对象的 'timeout'
事件的监听器中。
如果没有为请求、响应或服务器添加 'timeout'
监听器,则套接字超时时将被销毁。如果为请求、响应或服务器的 'timeout'
事件分配了处理程序,则必须显式处理超时的套接字。
response.socket
新增于: v0.3.0
对底层套接字的引用。通常用户不需要访问此属性。特别是,由于协议解析器连接到套接字的方式,套接字不会发出 'readable'
事件。在 response.end()
之后,该属性将被设置为 null。
import http from 'node:http'
const server = http
.createServer((req, res) => {
const ip = res.socket.remoteAddress
const port = res.socket.remotePort
res.end(`Your IP address is ${ip} and your source port is ${port}.`)
})
.listen(3000)
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> 之外的套接字类型,否则此属性保证是 <net.Socket> 类(<stream.Duplex> 的子类)的实例。
response.statusCode
新增于: v0.4.0
- <数字> 默认值:
200
当使用隐式头部(没有显式调用 response.writeHead()
)时,此属性控制在头部刷新时发送到客户端的状态码。
response.statusCode = 404
响应头部发送到客户端后,此属性指示已发送出的状态码。
response.statusMessage
新增于: v0.11.8
当使用隐式头部(没有显式调用 response.writeHead()
)时,此属性控制在头部刷新时发送到客户端的状态消息。如果此属性留空为 undefined
,则将使用状态码的标准消息。
response.statusMessage = 'Not found'
响应头部发送到客户端后,此属性指示已发送出的状态消息。
response.strictContentLength
新增于:v18.10.0, v16.18.0
- <布尔值> 默认值:
false
如果设置为 true
,Node.js 将检查 Content-Length
头部值与正文(以字节为单位)的大小是否相等。Content-Length
头部值不匹配将导致抛出 Error
,其 code:
为 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'
。
response.uncork()
新增于:v13.2.0, v12.16.0
response.writableEnded
新增于:v12.9.0
在调用 response.end()
之后为 true
。此属性不指示数据是否已刷新,为此请改用 response.writableFinished
。
response.writableFinished
新增于: v12.7.0
在发出 'finish'
事件之前的瞬间,如果所有数据都已刷新到底层系统,则为 true
。
response.write(chunk[, encoding][, callback])
[历史记录]
版本 | 变更 |
---|---|
v15.0.0 | chunk 参数现在可以是 Uint8Array 。 |
v0.1.29 | 新增于: v0.1.29 |
如果调用此方法且未调用 response.writeHead()
,它将切换到隐式标头模式并刷新隐式标头。
这会发送响应正文的一部分。可以多次调用此方法以提供正文的连续部分。
如果在 createServer
中将 rejectNonStandardBodyWrites
设置为 true,则当请求方法或响应状态不支持内容时,不允许写入正文。如果尝试为 HEAD 请求写入正文或作为 204
或 304
响应的一部分写入正文,则会同步抛出代码为 ERR_HTTP_BODY_NOT_ALLOWED
的 Error
。
chunk
可以是字符串或缓冲区。如果 chunk
是字符串,则第二个参数指定如何将其编码为字节流。当此数据块被刷新时,将调用 callback
。
这是原始的 HTTP 正文,与可能使用的更高级别的多部分正文编码无关。
第一次调用 response.write()
时,它将把缓冲的标头信息和正文的第一块数据发送到客户端。第二次调用 response.write()
时,Node.js 假设数据将被流式传输,并单独发送新数据。也就是说,响应缓冲到正文的第一块数据。
如果所有数据都成功刷新到内核缓冲区,则返回 true
。如果所有或部分数据排队在用户内存中,则返回 false
。缓冲区再次可用时将发出 'drain'
事件。
response.writeContinue()
新增于:v0.3.0
向客户端发送 HTTP/1.1 100 Continue 消息,指示应该发送请求体。参见 Server
上的 'checkContinue'
事件。
response.writeEarlyHints(hints[, callback])
[历史]
版本 | 变更 |
---|---|
v18.11.0 | 允许将提示作为对象传递。 |
v18.11.0 | 新增于:v18.11.0 |
向客户端发送 HTTP/1.1 103 Early Hints 消息,其中包含 Link 头部,指示用户代理可以预加载/预连接链接的资源。hints
是一个对象,包含要与早期提示消息一起发送的头的值。可选的 callback
参数将在响应消息写入后被调用。
示例
const earlyHintsLink = '</styles.css>; rel=preload; as=style'
response.writeEarlyHints({
link: earlyHintsLink,
})
const earlyHintsLinks = ['</styles.css>; rel=preload; as=style', '</scripts.js>; rel=preload; as=script']
response.writeEarlyHints({
link: earlyHintsLinks,
'x-trace-id': 'id for diagnostics',
})
const earlyHintsCallback = () => console.log('early hints message sent')
response.writeEarlyHints(
{
link: earlyHintsLinks,
},
earlyHintsCallback
)
response.writeHead(statusCode[, statusMessage][, headers])
[历史]
版本 | 变更 |
---|---|
v14.14.0 | 允许将 headers 作为数组传递。 |
v11.10.0, v10.17.0 | 从 writeHead() 返回 this 以允许与 end() 链式调用。 |
v5.11.0, v4.4.5 | 如果 statusCode 不是 [100, 999] 范围内的数字,则抛出 RangeError 。 |
v0.1.30 | 新增于:v0.1.30 |
statusCode
<数字>statusMessage
<字符串>headers
<对象> | <数组>- 返回值: <http.ServerResponse>
向请求发送响应头。状态码是一个三位数的 HTTP 状态码,例如 404
。最后一个参数 headers
是响应头。可以选择性地提供一个易于理解的 statusMessage
作为第二个参数。
headers
可以是一个数组,其中键和值在同一个列表中。它不是一个元组列表。因此,偶数偏移量是键值,奇数偏移量是关联的值。该数组与 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()
设置了 headers 时,它们将与传递给 response.writeHead()
的任何 headers 合并,传递给 response.writeHead()
的 headers 优先。
如果调用此方法并且没有调用 response.setHeader()
,它将直接将提供的 header 值写入网络通道,而不会在内部缓存,并且 header 上的 response.getHeader()
将不会产生预期的结果。如果需要逐步填充 headers 并可能将来检索和修改,请改用 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
和已传输正文的长度是否相等。
尝试设置包含无效字符的 header 字段名称或值将导致抛出 [Error
][]。
response.writeProcessing()
新增于:v10.0.0
向客户端发送 HTTP/1.1 102 Processing 消息,指示应发送请求正文。
类:http.IncomingMessage
[历史]
版本 | 变更 |
---|---|
v15.5.0 | destroyed 值在传入数据被消耗后返回 true 。 |
v13.1.0, v12.16.0 | readableHighWaterMark 值与套接字的值一致。 |
v0.1.17 | 新增于:v0.1.17 |
IncomingMessage
对象由 http.Server
或 http.ClientRequest
创建,并分别作为第一个参数传递给 'request'
和 'response'
事件。它可用于访问响应状态、报头和数据。
与其 socket
值(它是 <stream.Duplex>
的子类)不同,IncomingMessage
本身继承自 <stream.Readable>
,并被单独创建以解析和发出传入的 HTTP 报头和有效负载,因为在保持活动连接的情况下,底层套接字可能会被重复使用多次。
事件:'aborted'
添加于:v0.3.8
自 v17.0.0, v16.12.0 起已弃用
当请求被中止时发出。
事件:'close'
[历史记录]
版本 | 变更 |
---|---|
v16.0.0 | 请求完成后现在会发出 close 事件,而不是底层套接字关闭时发出。 |
v0.4.2 | 添加于:v0.4.2 |
当请求完成时发出。
message.aborted
添加于:v10.1.0
自 v17.0.0, v16.12.0 起已弃用
[稳定性:0 - 已弃用]
稳定性:0 稳定性:0 - 已弃用。请检查来自 <stream.Readable> 的 message.destroyed
。
如果请求被中止,则 message.aborted
属性将为 true
。
message.complete
新增于: v0.3.0
如果已接收并成功解析完整的 HTTP 消息,则 message.complete
属性将为 true
。
此属性特别有用,可以用来确定在连接终止之前客户端或服务器是否已完全传输消息:
const req = http.request(
{
host: '127.0.0.1',
port: 8080,
method: 'POST',
},
res => {
res.resume()
res.on('end', () => {
if (!res.complete) console.error('消息仍在发送过程中连接被终止')
})
}
)
message.connection
新增于: v0.1.90
自 v16.0.0 起已弃用
[稳定性: 0 - 已弃用]
稳定性: 0 稳定性: 0 - 已弃用。请使用 message.socket
。
message.socket
的别名。
message.destroy([error])
[历史]
版本 | 变更 |
---|---|
v14.5.0, v12.19.0 | 为与其他可读流保持一致,该函数返回 this 。 |
v0.3.0 | v0.3.0 版本中添加 |
调用接收 IncomingMessage
的套接字上的 destroy()
。如果提供了 error
,则在套接字上发出 'error'
事件,并将 error
作为参数传递给该事件上的任何侦听器。
message.headers
[历史]
版本 | 变更 |
---|---|
v19.5.0, v18.14.0 | http.request() 和 http.createServer() 函数中的 joinDuplicateHeaders 选项确保不会丢弃重复的标头,而是根据 RFC 9110 第 5.3 节使用逗号分隔符将其组合。 |
v15.1.0 | message.headers 现在使用原型上的访问器属性进行延迟计算,并且不再是可枚举的。 |
v0.1.5 | v0.1.5 版本中添加 |
请求/响应标头对象。
标头名称和值的键值对。标头名称小写。
// 打印类似以下内容:
//
// { '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
标头,值将使用;
连接在一起。 - 对于所有其他标头,值将使用
,
连接在一起。
message.headersDistinct
新增于:v18.3.0, v16.17.0
类似于 message.headers
,但是没有连接逻辑,即使只接收一次的头部值也始终为字符串数组。
// 打印类似以下内容:
//
// { 'user-agent': ['curl/7.22.0'],
// host: ['127.0.0.1:8000'],
// accept: ['*/*'] }
console.log(request.headersDistinct)
message.httpVersion
新增于:v0.1.1
对于服务器请求,表示客户端发送的 HTTP 版本。对于客户端响应,表示已连接服务器的 HTTP 版本。可能是 '1.1'
或 '1.0'
。
此外,message.httpVersionMajor
是第一个整数,message.httpVersionMinor
是第二个整数。
message.method
新增于:v0.1.1
仅对从 http.Server
获取的请求有效。
请求方法,以字符串形式表示。只读。例如:'GET'
,'DELETE'
。
message.rawHeaders
新增于:v0.11.6
原始请求/响应头列表,完全按照接收到的顺序排列。
键和值位于同一列表中。它不是元组列表。因此,偶数偏移量是键值,奇数偏移量是关联的值。
头名称不转换为小写,并且不合并重复项。
// 打印结果类似:
//
// [ '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
新增于:v0.11.6
原始请求/响应尾部键值,完全按照接收到的顺序排列。仅在'end'
事件中填充。
message.setTimeout(msecs[, callback])
新增于:v0.5.9
msecs
<number>callback
<Function>- 返回值: <http.IncomingMessage>
调用message.socket.setTimeout(msecs, callback)
。
message.socket
新增于:v0.3.0
与连接关联的 net.Socket
对象。
在支持 HTTPS 的情况下,使用 request.socket.getPeerCertificate()
获取客户端的认证详细信息。
除非用户指定了除 <net.Socket>
之外的套接字类型或内部将其设为 null,否则此属性保证为 <net.Socket>
类(<stream.Duplex>
](/zh/api/stream#class-streamduplex) 的子类)的实例。
message.statusCode
新增于:v0.1.1
仅对从 http.ClientRequest
获取的响应有效。
3 位数的 HTTP 响应状态码。例如 404
。
message.statusMessage
新增于:v0.11.10
仅对从 http.ClientRequest
获取的响应有效。
HTTP 响应状态消息(原因短语)。例如 OK
或 Internal Server Error
。
message.trailers
新增于:v0.3.0
请求/响应尾部对象。仅在 'end'
事件中填充。
message.trailersDistinct
新增于:v18.3.0, v16.17.0
类似于 message.trailers
,但是没有连接逻辑,并且值始终是字符串数组,即使只接收一次报头也是如此。仅在 'end'
事件中填充。
message.url
新增于:v0.1.90
仅对从 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
未定义时:
$ 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
新增于: v0.1.17
- 继承自: <Stream>
此类作为http.ClientRequest
和http.ServerResponse
的父类。从 HTTP 事务参与者的角度来看,它是一个抽象的传出消息。
事件: 'drain'
新增于: v0.3.6
当消息的缓冲区再次可用时发出。
事件: 'finish'
新增于: v0.1.17
传输成功完成时发出。
事件: 'prefinish'
新增于: v0.11.6
调用outgoingMessage.end()
后发出。当事件发出时,所有数据都已处理,但不一定完全刷新。
outgoingMessage.addTrailers(headers)
新增于: v0.3.0
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)
新增于: v18.3.0, v16.17.0
name
<string> 头部名称value
<string> | <string[]> 头部值- 返回值: <this>
将单个头部值添加到头部对象。
如果值是一个数组,这等同于多次调用此方法。
如果头部之前没有值,这等同于调用 outgoingMessage.setHeader(name, value)
。
根据客户端请求或服务器创建时options.uniqueHeaders
的值,这最终会导致头部被发送多次或仅发送一次,其值使用;
连接。
outgoingMessage.connection
新增于: v0.3.0
自以下版本起已弃用: v15.12.0, v14.17.1
[稳定性: 0 - 已弃用]
稳定性: 0 稳定性: 0 - 已弃用: 请改用 outgoingMessage.socket
。
outgoingMessage.cork()
新增于: v13.2.0, v12.16.0
参见 writable.cork()
。
outgoingMessage.destroy([error])
新增于: v0.3.0
销毁消息。一旦套接字与消息关联并连接,该套接字也将被销毁。
outgoingMessage.end(chunk[, encoding][, callback])
[历史记录]
版本 | 变更 |
---|---|
v15.0.0 | chunk 参数现在可以是 Uint8Array 。 |
v0.11.6 | 添加 callback 参数。 |
v0.1.90 | 新增于: v0.1.90 |
chunk
<string> | <Buffer> | <Uint8Array>encoding
<string> 可选,默认值:utf8
callback
<Function> 可选- 返回值: <this>
结束传出的消息。如果正文的任何部分未发送,它将把它们刷新到底层系统。如果消息是分块的,它将发送终止块 0\r\n\r\n
,并发送尾部(如果有)。
如果指定了 chunk
,则等同于调用 outgoingMessage.write(chunk, encoding)
,然后调用 outgoingMessage.end(callback)
。
如果提供了 callback
,则当消息完成时将调用它(相当于 'finish'
事件的监听器)。
outgoingMessage.flushHeaders()
新增于: v1.6.0
刷新消息头。
出于效率考虑,Node.js 通常会缓冲消息头,直到调用 outgoingMessage.end()
或写入消息数据的第一个块。然后它尝试将消息头和数据打包到单个 TCP 数据包中。
这通常是理想的(它节省了一个 TCP 往返行程),但当第一个数据可能要到很久以后才发送时则不然。outgoingMessage.flushHeaders()
会绕过此优化并启动消息。
outgoingMessage.getHeader(name)
新增于: v0.4.0
name
<string> 头部名称- 返回值: <string> | <undefined>
获取具有给定名称的 HTTP 头部的值。如果未设置该头部,则返回值将为 undefined
。
outgoingMessage.getHeaderNames()
新增于: v7.7.0
- 返回值: <string[]>
返回一个数组,包含当前外发报头的唯一名称。所有名称都小写。
outgoingMessage.getHeaders()
新增于: v7.7.0
- 返回值: <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)
新增于: v7.7.0
如果传出报头中当前设置了由 name
标识的报头,则返回 true
。报头名称不区分大小写。
const hasContentType = outgoingMessage.hasHeader('content-type')
outgoingMessage.headersSent
新增于: v0.9.3
只读。如果报头已发送,则为 true
,否则为 false
。
outgoingMessage.pipe()
新增于: v9.0.0
覆盖从作为 http.OutgoingMessage
父类的旧版 Stream
类继承的 stream.pipe()
方法。
调用此方法将抛出 Error
,因为 outgoingMessage
是只写流。
outgoingMessage.removeHeader(name)
新增于: v0.4.0
name
<string> 报头名称
移除已排队等待隐式发送的报头。
outgoingMessage.removeHeader('Content-Encoding')
outgoingMessage.setHeader(name, value)
新增于:v0.4.0
设置单个头部值。如果头部已存在于待发送的头部中,其值将被替换。使用字符串数组发送具有相同名称的多个头部。
outgoingMessage.setHeaders(headers)
新增于:v19.6.0, v18.15.0
为隐式头部设置多个头部值。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(msesc[, callback])
新增于:v0.9.12
msesc
<number>callback
<Function> 超时时调用的可选函数。与绑定到timeout
事件相同。- 返回值: <this>
一旦套接字与消息关联并连接,socket.setTimeout()
将以 msecs
作为第一个参数被调用。
outgoingMessage.socket
新增于:v0.3.0
底层套接字的引用。通常,用户不需要访问此属性。
调用 outgoingMessage.end()
后,此属性将被置空。
outgoingMessage.uncork()
新增于:v13.2.0, v12.16.0
outgoingMessage.writableCorked
新增于: v13.2.0, v12.16.0
outgoingMessage.cork()
方法被调用的次数。
outgoingMessage.writableEnded
新增于: v12.9.0
如果已调用 outgoingMessage.end()
则为 true
。此属性并不指示数据是否已被刷新。为此目的,请改用 message.writableFinished
。
outgoingMessage.writableFinished
新增于: v12.7.0
如果所有数据都已刷新到底层系统,则为 true
。
outgoingMessage.writableHighWaterMark
新增于: v12.9.0
如果已分配,则为底层套接字的 highWaterMark
。否则,当 writable.write()
开始返回 false 时,为默认缓冲区级别 (16384
)。
outgoingMessage.writableLength
新增于:v12.9.0
已缓冲字节数。
outgoingMessage.writableObjectMode
新增于:v12.9.0
始终为 false
。
outgoingMessage.write(chunk[, encoding][, callback])
[历史]
版本 | 变更 |
---|---|
v15.0.0 | chunk 参数现在可以是 Uint8Array 。 |
v0.11.6 | 添加了 callback 参数。 |
v0.1.29 | 新增于:v0.1.29 |
chunk
<string> | <Buffer> | <Uint8Array>encoding
<string> 默认值:utf8
callback
<Function>- 返回值: <boolean>
发送一部分正文。此方法可以多次调用。
encoding
参数仅在 chunk
为字符串时相关。默认为 'utf8'
。
callback
参数是可选的,当这部分数据被刷新时将被调用。
如果所有数据都成功刷新到内核缓冲区,则返回 true
。如果所有或部分数据被排队到用户内存中,则返回 false
。缓冲区再次可用时,将发出 'drain'
事件。
http.METHODS
新增于: v0.11.8
解析器支持的 HTTP 方法列表。
http.STATUS_CODES
新增于: v0.1.22
所有标准 HTTP 响应状态码的集合,以及每个状态码的简短描述。例如,http.STATUS_CODES[404] === 'Not Found'
。
http.createServer([options][, requestListener])
[历史]
版本 | 变更 |
---|---|
v20.1.0, v18.17.0 | 现在支持 highWaterMark 选项。 |
v18.0.0 | 现在支持 requestTimeout 、headersTimeout 、keepAliveTimeout 和 connectionsCheckingInterval 选项。 |
v18.0.0 | noDelay 选项现在默认为 true 。 |
v17.7.0, v16.15.0 | 现在支持 noDelay 、keepAlive 和 keepAliveInitialDelay 选项。 |
v13.3.0 | 现在支持 maxHeaderSize 选项。 |
v13.8.0, v12.15.0, v10.19.0 | 现在支持 insecureHTTPParser 选项。 |
v9.6.0, v8.12.0 | 现在支持 options 参数。 |
v0.1.13 | 新增于: v0.1.13 |
options
<Object>connectionsCheckingInterval
: 设置以毫秒为单位的间隔值,用于检查不完整请求中的请求和标头超时。默认值:30000
。headersTimeout
: 设置以毫秒为单位的超时值,用于接收来自客户端的完整 HTTP 标头。有关更多信息,请参见server.headersTimeout
。默认值:60000
。highWaterMark
<number> 可选地覆盖所有socket
的readableHighWaterMark
和writableHighWaterMark
。这会影响IncomingMessage
和ServerResponse
的highWaterMark
属性。默认值: 请参见stream.getDefaultHighWaterMark()
。insecureHTTPParser
<boolean> 如果设置为true
,它将使用启用了宽松标志的 HTTP 解析器。应避免使用不安全的解析器。有关更多信息,请参见--insecure-http-parser
。默认值:false
。IncomingMessage
<http.IncomingMessage> 指定要使用的IncomingMessage
类。用于扩展原始IncomingMessage
。默认值:IncomingMessage
。joinDuplicateHeaders
<boolean> 如果设置为true
,此选项允许使用逗号 (,
) 将请求中多个标头的字段行值连接起来,而不是丢弃重复项。有关更多信息,请参阅message.headers
。默认值:false
。keepAlive
<boolean> 如果设置为true
,它会在接收新的传入连接后立即在套接字上启用保持活动功能,类似于 [socket.setKeepAlive([enable][, initialDelay])
][socket.setKeepAlive(enable, initialDelay)
] 中所做的操作。默认值:false
。keepAliveInitialDelay
<number> 如果设置为正数,它将设置在空闲套接字上发送第一个保持活动探测之前的初始延迟。默认值:0
。keepAliveTimeout
: 服务器在完成写入最后一个响应后需要等待附加传入数据(以毫秒为单位)的空闲时间,然后才能销毁套接字。有关更多信息,请参见server.keepAliveTimeout
。默认值:5000
。maxHeaderSize
<number> 可选地覆盖此服务器接收的请求的--max-http-header-size
值,即请求标头(以字节为单位)的最大长度。默认值: 16384 (16 KiB)。noDelay
<boolean> 如果设置为true
,它会在接收新的传入连接后立即禁用 Nagle 算法的使用。默认值:true
。requestTimeout
: 设置以毫秒为单位的超时值,用于接收来自客户端的整个请求。有关更多信息,请参见server.requestTimeout
。默认值:300000
。requireHostHeader
<boolean> 如果设置为true
,它会强制服务器使用 400(错误请求)状态代码响应任何缺少 Host 标头的 HTTP/1.1 请求消息(如规范规定)。默认值:true
。ServerResponse
<http.ServerResponse> 指定要使用的ServerResponse
类。用于扩展原始ServerResponse
。默认值:ServerResponse
。uniqueHeaders
<Array> 应该只发送一次的响应标头列表。如果标头的值是数组,则将使用;
连接项目。rejectNonStandardBodyWrites
<boolean> 如果设置为true
,则在写入没有正文的 HTTP 响应时会引发错误。默认值:false
。
requestListener
<Function>返回值: <http.Server>
返回 http.Server
的一个新实例。
requestListener
是一个函数,它会自动添加到 'request'
事件中。
import http from 'node:http'
// 创建一个本地服务器来接收数据
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(
JSON.stringify({
data: 'Hello World!',
})
)
})
server.listen(8000)
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)
import http from 'node:http'
// 创建一个本地服务器来接收数据
const server = http.createServer()
// 监听 request 事件
server.on('request', (request, 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()
// 监听 request 事件
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])
[历史]
版本 | 变更 |
---|---|
v10.9.0 | 现在可以与单独的 options 对象一起传递 url 参数。 |
v7.5.0 | options 参数可以是 WHATWG URL 对象。 |
v0.3.6 | 新增于:v0.3.6 |
url
<字符串> | <URL>options
<对象> 接受与http.request()
相同的options
,方法默认为 GET。callback
<函数>- 返回值: <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('请求失败。\n' + `状态代码:${statusCode}`)
} else if (!/^application\/json/.test(contentType)) {
error = new Error('无效的内容类型。\n' + `预期 application/json 但收到 ${contentType}`)
}
if (error) {
console.error(error.message)
// 使用响应数据以释放内存
res.resume()
return
}
res.setEncoding('utf8')
let rawData = ''
res.on('data', chunk => {
rawData += chunk
})
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData)
console.log(parsedData)
} catch (e) {
console.error(e.message)
}
})
})
.on('error', e => {
console.error(`出现错误:${e.message}`)
})
// 创建本地服务器以接收数据
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
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 代理现在默认使用 HTTP Keep-Alive 和 5 秒超时。 |
v0.5.9 | 新增于:v0.5.9 |
Agent
的全局实例,用作所有 HTTP 客户端请求的默认值。它与默认的 Agent
配置不同,启用了 keepAlive
并设置了 5 秒的 timeout
。
http.maxHeaderSize
新增于:v11.6.0, v10.15.0
只读属性,指定 HTTP 头的最大允许大小(以字节为单位)。默认为 16 KiB。可以使用 --max-http-header-size
CLI 选项进行配置。
这可以通过传递 maxHeaderSize
选项来覆盖服务器和客户端请求的设置。
http.request(options[, callback])
http.request(url[, options][, callback])
[历史]
版本 | 变更 |
---|---|
v16.7.0, v14.18.0 | 使用 URL 对象时,解析的用户名和密码现在将被正确地 URI 解码。 |
v15.3.0, v14.17.0 | 可以使用 AbortSignal 中断请求。 |
v13.3.0 | 现在支持 maxHeaderSize 选项。 |
v13.8.0, v12.15.0, v10.19.0 | 现在支持 insecureHTTPParser 选项。 |
v10.9.0 | 现在可以同时传递 url 参数和单独的 options 对象。 |
v7.5.0 | options 参数可以是 WHATWG URL 对象。 |
v0.3.6 | 新增于:v0.3.6 |
options
<Object>
agent
<http.Agent>
|<boolean>
控制Agent
行为。可能的值:undefined
(默认):为此主机和端口使用http.globalAgent
。Agent
对象:显式使用传入的Agent
。false
:导致使用具有默认值的新Agent
。auth
<string>
基本身份验证('user:password'
)以计算授权头。createConnection
<Function>
一个函数,当不使用agent
选项时,生成用于请求的套接字/流。这可以用来避免仅为了覆盖默认的createConnection
函数而创建自定义Agent
类。有关更多详细信息,请参阅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>
如果设置为true
,它将使用启用了宽松标志的 HTTP 解析器。应避免使用不安全的解析器。有关更多信息,请参阅--insecure-http-parser
。默认值:false
joinDuplicateHeaders
<boolean>
它使用,
将请求中多个头的字段行值连接起来,而不是丢弃重复项。有关更多信息,请参阅message.headers
。默认值:false
。localAddress
<string>
用于网络连接的本地接口。localPort
<number>
用于连接的本地端口。lookup
<Function>
自定义查找函数。默认值:dns.lookup()
。maxHeaderSize
<number>
可选地覆盖--max-http-header-size
的值(以字节为单位的响应头的最大长度),用于从服务器接收到的响应。**默认值:**16384 (16 KiB)。method
<string>
指定 HTTP 请求方法的字符串。默认值:'GET'
。path
<string>
请求路径。如果存在,应包含查询字符串。例如'/index.html?page=12'
。当请求路径包含非法字符时,会抛出异常。目前,只拒绝空格,但这在将来可能会改变。默认值:'/'
。port
<number>
远程服务器的端口。**默认值:**如果设置了defaultPort
,则为defaultPort
,否则为80
。protocol
<string>
要使用的协议。默认值:'http:'
。setDefaultHeaders
<boolean>
: 指定是否自动添加默认标头,例如Connection
、Content-Length
、Transfer-Encoding
和Host
。如果设置为false
,则必须手动添加所有必要的标头。默认为true
。setHost
<boolean>
: 指定是否自动添加Host
标头。如果提供,则会覆盖setDefaultHeaders
。默认为true
。signal
<AbortSignal>
: 一个AbortSignal
,可用于中止正在进行的请求。socketPath
<string>
Unix 域套接字。如果指定了host
或port
之一,则不能使用,因为它们指定了 TCP 套接字。timeout
<number>
: 一个数字,指定套接字超时(以毫秒为单位)。这将设置套接字连接之前的超时时间。uniqueHeaders
<Array>
一个请求头的列表,这些请求头应该只发送一次。如果头的值是一个数组,则项目将使用;
连接。
callback
<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()
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:')
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])
[历史]
版本 | 变更 |
---|---|
v19.5.0, v18.14.0 | 添加了 label 参数。 |
v14.3.0 | v14.3.0 中添加 |
对提供的 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 name must be a valid HTTP token [""]'
}
const { validateHeaderName } = require('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 name must be a valid HTTP token [""]'
}
http.validateHeaderValue(name, value)
新增于: v14.3.0
对提供的 value
执行低级别验证,这些验证在调用 res.setHeader(name, value)
时会进行。
传入非法的 value
将导致抛出 TypeError
错误。
- 未定义的值错误由
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) // --> 'Invalid value "undefined" for header "x-my-header"'
}
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) // --> 'Invalid character in header content ["x-my-header"]'
}
const { validateHeaderValue } = require('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) // --> 'Invalid value "undefined" for header "x-my-header"'
}
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) // --> 'Invalid character in header content ["x-my-header"]'
}
http.setMaxIdleHTTPParsers(max)
新增于: v18.8.0, v16.18.0
max
<number> 默认值:1000
.
设置空闲 HTTP 解析器的最大数量。
WebSocket
新增于: v22.5.0
WebSocket
的浏览器兼容实现。