Node.js v21.7.2 文档
- Node.js v21.7.2
-
► 目录
- HTTP/2
- 确定加密支持是否不可用
- 核心 API
- 服务器端示例
- 客户端示例
- 类:
Http2Session
Http2Session
和套接字- 事件:
'close'
- 事件:
'connect'
- 事件:
'error'
- 事件:
'frameError'
- 事件:
'goaway'
- 事件:
'localSettings'
- 事件:
'ping'
- 事件:
'remoteSettings'
- 事件:
'stream'
- 事件:
'timeout'
http2session.alpnProtocol
http2session.close([callback])
http2session.closed
http2session.connecting
http2session.destroy([error][, code])
http2session.destroyed
http2session.encrypted
http2session.goaway([code[, lastStreamID[, opaqueData]]])
http2session.localSettings
http2session.originSet
http2session.pendingSettingsAck
http2session.ping([payload, ]callback)
http2session.ref()
http2session.remoteSettings
http2session.setLocalWindowSize(windowSize)
http2session.setTimeout(msecs, callback)
http2session.socket
http2session.state
http2session.settings([settings][, callback])
http2session.type
http2session.unref()
- 类:
ServerHttp2Session
- 类:
ClientHttp2Session
- 类:
Http2Stream
Http2Stream
生命周期- 事件:
'aborted'
- 事件:
'close'
- 事件:
'error'
- 事件:
'frameError'
- 事件:
'ready'
- 事件:
'timeout'
- 事件:
'trailers'
- 事件:
'wantTrailers'
http2stream.aborted
http2stream.bufferSize
http2stream.close(code[, callback])
http2stream.closed
http2stream.destroyed
http2stream.endAfterHeaders
http2stream.id
http2stream.pending
http2stream.priority(options)
http2stream.rstCode
http2stream.sentHeaders
http2stream.sentInfoHeaders
http2stream.sentTrailers
http2stream.session
http2stream.setTimeout(msecs, callback)
http2stream.state
http2stream.sendTrailers(headers)
- 类:
ClientHttp2Stream
- 类:
ServerHttp2Stream
- 类:
Http2Server
- 类:
Http2SecureServer
http2.createServer([options][, onRequestHandler])
http2.createSecureServer(options[, onRequestHandler])
http2.connect(authority[, options][, listener])
http2.constants
http2.getDefaultSettings()
http2.getPackedSettings([设置])
http2.getUnpackedSettings(buf)
http2.performServerHandshake(socket[, 选项])
http2.sensitiveHeaders
- Headers 对象
- Settings 对象
- 错误处理
- 标头名称和值中的无效字符处理
- 客户端上的推送流
- 支持
CONNECT
方法 - 扩展的
CONNECT
协议
- 兼容性 API
- ALPN 协商
- 类:
http2.Http2ServerRequest
- 事件:
'aborted'
- 事件:
'close'
request.aborted
request.authority
request.complete
request.connection
request.destroy([错误])
request.headers
request.httpVersion
request.method
request.rawHeaders
request.rawTrailers
request.scheme
request.setTimeout(msecs, callback)
request.socket
request.stream
request.trailers
request.url
- 事件:
- 类:
http2.Http2ServerResponse
- 事件:
'close'
- 事件:
'finish'
response.addTrailers(headers)
response.appendHeader(name, value)
response.connection
response.createPushResponse(headers, callback)
response.end([data[, encoding]][, callback])
response.finished
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.stream
response.writableEnded
response.write(chunk[, encoding][, callback])
response.writeContinue()
response.writeEarlyHints(hints)
response.writeHead(statusCode[, statusMessage][, headers])
- 事件:
- 收集 HTTP/2 性能指标
- 有关
:authority
和host
的说明
- HTTP/2
-
► 索引
- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲区
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入器 API
- 子进程
- 集群
- 命令行选项
- 控制台
- Corepack
- 加密
- 调试器
- 已弃用的 API
- 诊断通道
- DNS
- 域
- 错误
- 事件
- 文件系统
- 全局变量
- HTTP
- HTTP/2
- HTTPS
- 检查器
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:module
API - 模块:包
- 网络
- 操作系统
- 路径
- 性能钩子
- 权限
- 进程
- Punycode
- 查询字符串
- 命令行读取
- REPL
- 报告
- 单一可执行应用程序
- 流
- 字符串解码器
- 测试运行器
- 计时器
- TLS/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用工具
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- 工作线程
- Zlib
- ► 其他版本
- ► 选项
HTTP/2#
源代码: lib/http2.js
node:http2
模块提供了 HTTP/2 协议的实现。可以使用以下方法访问它
const http2 = require('node:http2');
确定加密支持是否不可用#
Node.js 可以在不包含对 node:crypto
模块的支持的情况下进行构建。在这种情况下,尝试从 node:http2
import
或调用 require('node:http2')
将导致抛出错误。
使用 CommonJS 时,可以使用 try/catch 捕获抛出的错误
let http2;
try {
http2 = require('node:http2');
} catch (err) {
console.error('http2 support is disabled!');
}
使用词法 ESM import
关键字时,只有在尝试加载模块之前注册了 process.on('uncaughtException')
的处理程序时才能捕获错误(例如,使用预加载模块)。
使用 ESM 时,如果代码有可能在未启用加密支持的 Node.js 版本上运行,请考虑使用 import()
函数,而不是词法 import
关键字
let http2;
try {
http2 = await import('node:http2');
} catch (err) {
console.error('http2 support is disabled!');
}
核心 API#
核心 API 提供了一个专门围绕对 HTTP/2 协议特性提供支持而设计的低级接口。它特别不适用于与现有的 HTTP/1 模块 API 兼容。但是,兼容性 API 适用。
http2
核心 API 在客户端和服务器之间的对称性比 http
API 高得多。例如,大多数事件(如 'error'
、'connect'
和 'stream'
)都可以由客户端代码或服务器端代码发出。
服务器端示例#
以下说明了使用核心 API 的简单 HTTP/2 服务器。由于没有已知的浏览器支持 未加密的 HTTP/2,因此在与浏览器客户端通信时,使用 http2.createSecureServer()
是必需的。
const http2 = require('node:http2');
const fs = require('node:fs');
const server = http2.createSecureServer({
key: fs.readFileSync('localhost-privkey.pem'),
cert: fs.readFileSync('localhost-cert.pem'),
});
server.on('error', (err) => console.error(err));
server.on('stream', (stream, headers) => {
// stream is a Duplex
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8443);
要为此示例生成证书和密钥,请运行
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
-keyout localhost-privkey.pem -out localhost-cert.pem
客户端示例#
以下说明 HTTP/2 客户端
const http2 = require('node:http2');
const fs = require('node:fs');
const client = http2.connect('https://127.0.0.1:8443', {
ca: fs.readFileSync('localhost-cert.pem'),
});
client.on('error', (err) => console.error(err));
const req = client.request({ ':path': '/' });
req.on('response', (headers, flags) => {
for (const name in headers) {
console.log(`${name}: ${headers[name]}`);
}
});
req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => {
console.log(`\n${data}`);
client.close();
});
req.end();
类:Http2Session
#
http2.Http2Session
类的实例表示 HTTP/2 客户端和服务器之间的活动通信会话。此类的实例不旨在由用户代码直接构建。
每个 Http2Session
实例都会表现出略有不同的行为,具体取决于它是作为服务器还是客户端运行。http2session.type
属性可用于确定 Http2Session
的运行模式。在服务器端,用户代码很少有机会直接使用 Http2Session
对象,大多数操作通常通过与 Http2Server
或 Http2Stream
对象的交互进行。
用户代码不会直接创建 Http2Session
实例。当收到新的 HTTP/2 连接时,Http2Server
实例会创建服务器端的 Http2Session
实例。使用 http2.connect()
方法创建客户端端的 Http2Session
实例。
Http2Session
和套接字#
创建每个 Http2Session
实例时,都会将其与一个 net.Socket
或 tls.TLSSocket
关联。销毁 Socket
或 Http2Session
时,两者都会被销毁。
由于 HTTP/2 协议施加了特定的序列化和处理要求,因此不建议用户代码从绑定到 Http2Session
的 Socket
实例读取数据或向其写入数据。这样做可能会使 HTTP/2 会话进入不确定的状态,导致会话和套接字无法使用。
一旦 Socket
绑定到 Http2Session
,用户代码应仅依赖 Http2Session
的 API。
事件:'close'
#
销毁 Http2Session
后,将触发 'close'
事件。其监听器不期望有任何参数。
事件:'connect'
#
session
<Http2Session>socket
<net.Socket>
成功将 Http2Session
连接到远程对等方且可以开始通信后,将触发 'connect'
事件。
用户代码通常不会直接监听此事件。
事件:'error'
#
error
<Error>
当在处理 Http2Session
期间发生错误时,会发出 'error'
事件。
事件:'frameError'
#
当在尝试在会话上发送帧时发生错误时,会发出 'frameError'
事件。如果无法发送的帧与特定的 Http2Stream
关联,则会尝试在 Http2Stream
上发出 'frameError'
事件。
如果 'frameError'
事件与流关联,则该流将在 'frameError'
事件后立即关闭并销毁。如果该事件未与流关联,则 Http2Session
将在 'frameError'
事件后立即关闭。
事件:'goaway'
#
errorCode
<number>GOAWAY
帧中指定的 HTTP/2 错误代码。lastStreamID
<number> 远程对等方成功处理的最后一个流的 ID(如果未指定 ID,则为0
)。opaqueData
<Buffer> 如果在GOAWAY
帧中包含了其他不透明数据,则会传递一个包含该数据的Buffer
实例。
当收到 GOAWAY
帧时,会发出 'goaway'
事件。
当发出 'goaway'
事件时,Http2Session
实例将自动关闭。
事件:'localSettings'
#
settings
<HTTP/2 设置对象> 收到的SETTINGS
帧的副本。
当收到确认的 SETTINGS
帧时,将发出 'localSettings'
事件。
当使用 http2session.settings()
提交新设置时,修改后的设置在发出 'localSettings'
事件之前不会生效。
session.settings({ enablePush: false });
session.on('localSettings', (settings) => {
/* Use the new settings */
});
事件:'ping'
#
payload
<Buffer>PING
帧 8 字节有效负载
每当从连接的对等方收到 PING
帧时,都会发出 'ping'
事件。
事件:'remoteSettings'
#
settings
<HTTP/2 设置对象> 收到的SETTINGS
帧的副本。
当从连接的对等方收到新的 SETTINGS
帧时,将发出 'remoteSettings'
事件。
session.on('remoteSettings', (settings) => {
/* Use the new settings */
});
事件:'stream'
#
stream
<Http2Stream> 对流的引用headers
<HTTP/2 Headers Object> 描述标头的对象flags
<number> 关联的数字标志rawHeaders
<Array> 包含原始标头名称及其各自值的数组。
当创建新的 Http2Stream
时,将发出 'stream'
事件。
const http2 = require('node:http2');
session.on('stream', (stream, headers, flags) => {
const method = headers[':method'];
const path = headers[':path'];
// ...
stream.respond({
':status': 200,
'content-type': 'text/plain; charset=utf-8',
});
stream.write('hello ');
stream.end('world');
});
在服务器端,用户代码通常不会直接侦听此事件,而是会为 http2.createServer()
和 http2.createSecureServer()
返回的 net.Server
或 tls.Server
实例发出的 'stream'
事件注册一个处理程序,如下面的示例所示
const http2 = require('node:http2');
// Create an unencrypted HTTP/2 server
const server = http2.createServer();
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.on('error', (error) => console.error(error));
stream.end('<h1>Hello World</h1>');
});
server.listen(8000);
尽管 HTTP/2 流和网络套接字不是 1:1 对应关系,但网络错误会破坏每个单独的流,并且必须在流级别进行处理,如上所示。
事件:'timeout'
#
在使用 http2session.setTimeout()
方法为该 Http2Session
设置超时时间后,如果在配置的毫秒数后 Http2Session
上没有活动,则会发出 'timeout'
事件。其侦听器不期望任何参数。
session.setTimeout(2000);
session.on('timeout', () => { /* .. */ });
http2session.alpnProtocol
#
如果 Http2Session
尚未连接到套接字,则值将为 undefined
,如果 Http2Session
未连接到 TLSSocket
,则值为 h2c
,或者将返回已连接的 TLSSocket
自身 alpnProtocol
属性的值。
http2session.close([callback])
#
callback
<Function>
优雅地关闭 Http2Session
,允许任何现有流自行完成,并防止创建新的 Http2Stream
实例。关闭后,如果不存在打开的 Http2Stream
实例,可能会调用 http2session.destroy()
。
如果指定,则 callback
函数将注册为 'close'
事件的处理程序。
http2session.closed
#
如果此 Http2Session
实例已关闭,则为 true
,否则为 false
。
http2session.connecting
#
如果此 Http2Session
实例仍在连接,则为 true
,在发出 connect
事件和/或调用 http2.connect
回调之前,将设置为 false
。
http2session.destroy([error][, code])
#
error
<Error> 如果Http2Session
因错误而被销毁,则为Error
对象。code
<number> 在最终GOAWAY
帧中发送的 HTTP/2 错误代码。如果未指定,并且error
不为 undefined,则默认为INTERNAL_ERROR
,否则默认为NO_ERROR
。
立即终止 Http2Session
和关联的 net.Socket
或 tls.TLSSocket
。
销毁后,Http2Session
将发出 'close'
事件。如果 error
不为 undefined,则在 'close'
事件之前会立即发出 'error'
事件。
如果与 Http2Session
关联的任何剩余打开 Http2Streams
,这些 Http2Streams
也将被销毁。
http2session.destroyed
#
如果此 Http2Session
实例已销毁且不再需要使用,则为 true
,否则为 false
。
http2session.encrypted
#
如果 Http2Session
会话套接字尚未连接,则值为 undefined
;如果 Http2Session
使用 TLSSocket
连接,则值为 true
;如果 Http2Session
连接到任何其他类型的套接字或流,则值为 false
。
http2session.goaway([code[, lastStreamID[, opaqueData]]])
#
code
<number> HTTP/2 错误代码lastStreamID
<number> 最后处理的Http2Stream
的数字 IDopaqueData
<Buffer> | <TypedArray> | <DataView>TypedArray
或DataView
实例,其中包含要随GOAWAY
帧一起传递的其他数据。
向连接的对等方传输 GOAWAY
帧,而不关闭 Http2Session
。
http2session.localSettings
#
描述此 Http2Session
的当前本地设置的无原型对象。本地设置是特定于此 Http2Session
实例的。
http2session.originSet
#
如果 Http2Session
连接到 TLSSocket
,则 originSet
属性将返回一个 Array
,其中包含 Http2Session
可能被认为具有权威性的源。
仅在使用安全的 TLS 连接时,originSet
属性才可用。
http2session.pendingSettingsAck
#
指示 Http2Session
当前是否正在等待已发送 SETTINGS
帧的确认。在调用 http2session.settings()
方法后,将为 true
。一旦所有已发送 SETTINGS
帧都被确认,将为 false
。
http2session.ping([payload, ]callback)
#
payload
<Buffer> | <TypedArray> | <DataView> 可选 ping 有效负载。callback
<Function>- 返回:<boolean>
向已连接的 HTTP/2 对等方发送 PING
帧。必须提供 callback
函数。如果已发送 PING
,该方法将返回 true
,否则返回 false
。
未完成(未确认)ping 的最大数量由 maxOutstandingPings
配置选项确定。默认最大值为 10。
如果提供,payload
必须是包含 8 字节数据的 Buffer
、TypedArray
或 DataView
,这些数据将随 PING
一起传输并随 ping 确认一起返回。
回调将使用三个参数调用:一个错误参数(如果 PING
已成功确认,则该参数将为 null
)、一个 duration
参数(报告从发送 ping 到收到确认所经过的毫秒数)和一个包含 8 字节 PING
有效负载的 Buffer
。
session.ping(Buffer.from('abcdefgh'), (err, duration, payload) => {
if (!err) {
console.log(`Ping acknowledged in ${duration} milliseconds`);
console.log(`With payload '${payload.toString()}'`);
}
});
如果未指定 payload
参数,则默认有效负载将是 64 位时间戳(小端),标记 PING
持续时间的开始。
http2session.ref()
#
在此 Http2Session
实例的底层 net.Socket
上调用 ref()
。
http2session.remoteSettings
#
一个无原型对象,描述此 Http2Session
的当前远程设置。远程设置由已连接 HTTP/2 对等方设置。
http2session.setLocalWindowSize(windowSize)
#
windowSize
<number>
设置本地端点的窗口大小。windowSize
是要设置的总窗口大小,而不是增量。
const http2 = require('node:http2');
const server = http2.createServer();
const expectedWindowSize = 2 ** 20;
server.on('session', (session) => {
// Set local window size to be 2 ** 20
session.setLocalWindowSize(expectedWindowSize);
});
对于 http2 客户端,正确的事件是 'connect'
或 'remoteSettings'
。
http2session.setTimeout(msecs, callback)
#
msecs
<number>callback
<Function>
用于设置一个回调函数,当 Http2Session
在 msecs
毫秒后没有活动时调用该函数。给定的 callback
会作为 'timeout'
事件的监听器进行注册。
http2session.socket
#
返回一个 Proxy
对象,该对象充当 net.Socket
(或 tls.TLSSocket
),但将可用方法限制为可安全用于 HTTP/2 的方法。
destroy
、emit
、end
、pause
、read
、resume
和 write
会抛出一个代码为 ERR_HTTP2_NO_SOCKET_MANIPULATION
的错误。有关更多信息,请参阅 Http2Session
和套接字。
setTimeout
方法将在该 Http2Session
上调用。
所有其他交互都将直接路由到套接字。
http2session.state
#
提供有关 Http2Session
当前状态的各种信息。
- <对象>
effectiveLocalWindowSize
<数字>Http2Session
的当前本地(接收)流控制窗口大小。effectiveRecvDataLength
<数字> 自上次流控制WINDOW_UPDATE
以来已接收的当前字节数。nextStreamID
<数字> 此Http2Session
下次创建新的Http2Stream
时要使用的数字标识符。localWindowSize
<数字> 远程对等方可以在不收到WINDOW_UPDATE
的情况下发送的字节数。lastProcStreamID
<数字> 最近收到HEADERS
或DATA
帧的Http2Stream
的数字 ID。remoteWindowSize
<数字> 此Http2Session
可以在不收到WINDOW_UPDATE
的情况下发送的字节数。outboundQueueSize
<数字> 此Http2Session
的出站队列中当前的帧数。deflateDynamicTableSize
<数字> 出站标头压缩状态表的当前大小(以字节为单位)。inflateDynamicTableSize
<数字> 入站标头压缩状态表的当前大小(以字节为单位)。
描述此 Http2Session
当前状态的对象。
http2session.settings([settings][, callback])
#
settings
<HTTP/2 设置对象>callback
<函数> 会话连接后或会话已连接后立即调用的回调。err
<Error> | <null>settings
<HTTP/2 设置对象> 已更新的settings
对象。duration
<整数>
更新此 Http2Session
的当前本地设置,并向已连接的 HTTP/2 对等方发送新的 SETTINGS
帧。
调用后,在会话等待远程对等方确认新设置时,http2session.pendingSettingsAck
属性将为 true
。
新设置在收到 SETTINGS
确认并发出 'localSettings'
事件之前不会生效。在确认仍处于挂起状态时,可以发送多个 SETTINGS
帧。
http2session.type
#
如果此 Http2Session
实例是服务器,则 http2session.type
将等于 http2.constants.NGHTTP2_SESSION_SERVER
;如果该实例是客户端,则将等于 http2.constants.NGHTTP2_SESSION_CLIENT
。
http2session.unref()
#
在此 Http2Session
实例的基础 net.Socket
上调用 unref()
。
类:ServerHttp2Session
#
serverhttp2session.altsvc(alt, originOrStream)
#
alt
<字符串> 备用服务配置的描述,如 RFC 7838 中所定义。originOrStream
<数字> | <字符串> | <URL> | <Object> 指定来源的 URL 字符串(或具有origin
属性的Object
),或由http2stream.id
属性给出的活动Http2Stream
的数字标识符。
向已连接的客户端提交一个 ALTSVC
帧(如 RFC 7838 中所定义)。
const http2 = require('node:http2');
const server = http2.createServer();
server.on('session', (session) => {
// Set altsvc for origin https://example.org:80
session.altsvc('h2=":8000"', 'https://example.org:80');
});
server.on('stream', (stream) => {
// Set altsvc for a specific stream
stream.session.altsvc('h2=":8000"', stream.id);
});
发送带有特定流 ID 的 ALTSVC
帧表示备用服务与给定 Http2Stream
的源关联。
alt
和 origin 字符串必须只包含 ASCII 字节,并且严格解释为 ASCII 字节序列。特殊值 'clear'
可用于清除给定域的任何先前设置的备用服务。
当为 originOrStream
参数传递字符串时,它将被解析为 URL,并且将派生出 origin。例如,HTTP URL 'https://example.org/foo/bar'
的 origin 是 ASCII 字符串 'https://example.org'
。如果给定字符串无法解析为 URL 或无法派生出有效的 origin,则会抛出错误。
URL
对象或具有 origin
属性的任何对象都可以作为 originOrStream
传递,在这种情况下,将使用 origin
属性的值。origin
属性的值必须是正确序列化的 ASCII origin。
指定备用服务#
alt
参数的格式由 RFC 7838 严格定义为一个 ASCII 字符串,其中包含与特定主机和端口关联的“备用”协议的逗号分隔列表。
例如,值 'h2="example.org:81"'
表示 HTTP/2 协议可在主机 'example.org'
上的 TCP/IP 端口 81 上使用。主机和端口必须包含在引号 ("
) 字符内。
可以指定多个备用项,例如:'h2="example.org:81", h2=":82"'
。
协议标识符(示例中的 'h2'
)可以是任何有效的 ALPN 协议 ID。
Node.js 实现不会验证这些值语法,并且会按用户提供或从对等方接收到的方式传递这些值。
serverhttp2session.origin(...origins)
#
向已连接的客户端提交一个 ORIGIN
帧(如 RFC 8336 中所定义),以通告服务器能够提供权威响应的一组来源。
const http2 = require('node:http2');
const options = getSecureOptionsSomehow();
const server = http2.createSecureServer(options);
server.on('stream', (stream) => {
stream.respond();
stream.end('ok');
});
server.on('session', (session) => {
session.origin('https://example.com', 'https://example.org');
});
当一个字符串作为 origin
传递时,它将被解析为一个 URL,并且将派生出来源。例如,HTTP URL 'https://example.org/foo/bar'
的来源是 ASCII 字符串 'https://example.org'
。如果给定的字符串无法解析为 URL,或者无法派生出有效的来源,将会抛出一个错误。
一个 URL
对象,或任何具有 origin
属性的对象,可以作为 origin
传递,在这种情况下,将使用 origin
属性的值。origin
属性的值必须是正确序列化的 ASCII 来源。
或者,在使用 http2.createSecureServer()
方法创建新的 HTTP/2 服务器时,可以使用 origins
选项
const http2 = require('node:http2');
const options = getSecureOptionsSomehow();
options.origins = ['https://example.com', 'https://example.org'];
const server = http2.createSecureServer(options);
server.on('stream', (stream) => {
stream.respond();
stream.end('ok');
});
类:ClientHttp2Session
#
事件:'altsvc'
#
每当客户端收到一个 ALTSVC
帧时,都会发出 'altsvc'
事件。该事件会随 ALTSVC
值、来源和流 ID 一起发出。如果 ALTSVC
帧中未提供 origin
,则 origin
将为空字符串。
const http2 = require('node:http2');
const client = http2.connect('https://example.org');
client.on('altsvc', (alt, origin, streamId) => {
console.log(alt);
console.log(origin);
console.log(streamId);
});
事件:'origin'
#
origins
<string[]>
每当客户端收到一个 ORIGIN
帧时,都会发出 'origin'
事件。该事件会随一个 origin
字符串数组一起发出。http2session.originSet
将被更新,以包括收到的来源。
const http2 = require('node:http2');
const client = http2.connect('https://example.org');
client.on('origin', (origins) => {
for (let n = 0; n < origins.length; n++)
console.log(origins[n]);
});
仅在使用安全的 TLS 连接时才会发出 'origin'
事件。
clienthttp2session.request(headers[, options])
#
-
headers
<HTTP/2 标头对象> -
options
<对象>endStream
<布尔值> 如果Http2Stream
可写 端应最初关闭(例如在发送不应预期有效负载正文的GET
请求时),则为true
。exclusive
<布尔值> 当true
且parent
标识父级流时,创建的流将成为父级的唯一直接依赖项,所有其他现有依赖项将成为新创建流的依赖项。默认值:false
。parent
<数字> 指定新创建的流所依赖的流的数字标识符。weight
<数字> 指定流相对于具有相同parent
的其他流的相对依赖性。该值是介于1
和256
(包括)之间的数字。waitForTrailers
<布尔值> 当true
时,在发送最终DATA
帧后,Http2Stream
将发出'wantTrailers'
事件。signal
<AbortSignal> 可用于中止正在进行的请求的 AbortSignal。
仅适用于 HTTP/2 客户端 Http2Session
实例,http2session.request()
创建并返回一个 Http2Stream
实例,该实例可用于向已连接的服务器发送 HTTP/2 请求。
首次创建 ClientHttp2Session
时,套接字可能尚未连接。如果在此期间调用 clienthttp2session.request()
,实际请求将被延迟,直到套接字准备就绪。如果在执行实际请求之前关闭 session
,则会引发 ERR_HTTP2_GOAWAY_SESSION
。
此方法仅在 http2session.type
等于 http2.constants.NGHTTP2_SESSION_CLIENT
时可用。
const http2 = require('node:http2');
const clientSession = http2.connect('https://127.0.0.1:1234');
const {
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
} = http2.constants;
const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' });
req.on('response', (headers) => {
console.log(headers[HTTP2_HEADER_STATUS]);
req.on('data', (chunk) => { /* .. */ });
req.on('end', () => { /* .. */ });
});
当 options.waitForTrailers
选项被设置时,'wantTrailers'
事件在将要发送的有效载荷数据的最后一个块排队后立即发出。然后可以调用 http2stream.sendTrailers()
方法向对等方发送尾部标头。
当 options.waitForTrailers
被设置时,Http2Stream
在传输最终 DATA
帧时不会自动关闭。用户代码必须调用 http2stream.sendTrailers()
或 http2stream.close()
来关闭 Http2Stream
。
当 options.signal
使用 AbortSignal
设置,然后在相应的 AbortController
上调用 abort
时,请求将发出带有 AbortError
错误的 'error'
事件。
:method
和 :path
伪标头未在 headers
中指定,它们分别默认为
:method
='GET'
:path
=/
类:Http2Stream
#
Http2Stream
类的每个实例都表示通过 Http2Session
实例进行的双向 HTTP/2 通信流。任何单个 Http2Session
在其生命周期内最多可以有 231-1 个 Http2Stream
实例。
用户代码不会直接构造 Http2Stream
实例。相反,这些实例是通过 Http2Session
实例创建、管理并提供给用户代码的。在服务器上,Http2Stream
实例是在响应传入的 HTTP 请求(并通过 'stream'
事件传递给用户代码)时创建的,或者是在响应对 http2stream.pushStream()
方法的调用时创建的。在客户端上,Http2Stream
实例在调用 http2session.request()
方法时或在响应传入的 'push'
事件时创建并返回。
Http2Stream
类是 ServerHttp2Stream
和 ClientHttp2Stream
类的基础,每个类分别由服务器或客户端专门使用。
所有 Http2Stream
实例都是 Duplex
流。Duplex
的 Writable
端用于向连接的对等方发送数据,而 Readable
端用于接收由连接的对等方发送的数据。
Http2Stream
的默认文本字符编码是 UTF-8。使用 Http2Stream
发送文本时,使用 'content-type'
标头设置字符编码。
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
Http2Stream
生命周期#
创建#
在服务器端,ServerHttp2Stream
的实例会在以下情况创建:
- 接收到一个具有先前未使用流 ID 的新的 HTTP/2
HEADERS
帧; - 调用
http2stream.pushStream()
方法。
在客户端,ClientHttp2Stream
的实例会在调用 http2session.request()
方法时创建。
在客户端,如果父 Http2Session
尚未完全建立,则 http2session.request()
返回的 Http2Stream
实例可能无法立即使用。在这种情况下,对 Http2Stream
调用的操作将被缓冲,直到发出 'ready'
事件。用户代码很少需要直接处理 'ready'
事件。可以通过检查 http2stream.id
的值来确定 Http2Stream
的就绪状态。如果该值为 undefined
,则流尚未准备好使用。
销毁#
所有 Http2Stream
实例会在以下情况销毁:
- 连接的对等方接收到流的
RST_STREAM
帧,并且(仅适用于客户端流)已读取待处理数据。 - 调用
http2stream.close()
方法,并且(仅适用于客户端流)已读取待处理数据。 - 调用
http2stream.destroy()
或http2session.destroy()
方法。
当 Http2Stream
实例被销毁时,将尝试向连接的对等方发送 RST_STREAM
帧。
当 Http2Stream
实例被销毁时,将发出 'close'
事件。由于 Http2Stream
是 stream.Duplex
的一个实例,因此如果流数据当前正在流动,还将发出 'end'
事件。如果使用 Error
作为第一个参数调用 http2stream.destroy()
,则还可能发出 'error'
事件。
在 Http2Stream
被销毁后,http2stream.destroyed
属性将为 true
,并且 http2stream.rstCode
属性将指定 RST_STREAM
错误代码。一旦被销毁,Http2Stream
实例将不再可用。
事件:'aborted'
#
每当 Http2Stream
实例在通信过程中异常中止时,都会发出 'aborted'
事件。它的侦听器不期望任何参数。
只有当 Http2Stream
可写端尚未结束时,才会发出 'aborted'
事件。
事件:'close'
#
当 Http2Stream
被销毁时,会发出 'close'
事件。一旦发出此事件,Http2Stream
实例便不再可用。
可以使用 http2stream.rstCode
属性检索关闭流时使用的 HTTP/2 错误代码。如果代码是除 NGHTTP2_NO_ERROR
(0
) 之外的任何值,则还会发出 'error'
事件。
事件:'error'
#
error
<Error>
在处理 Http2Stream
期间发生错误时,会发出 'error'
事件。
事件:'frameError'
#
在尝试发送帧时发生错误时,会发出 'frameError'
事件。调用时,处理程序函数将接收一个标识帧类型的整型参数,以及一个标识错误代码的整型参数。Http2Stream
实例将在发出 'frameError'
事件后立即被销毁。
事件:'ready'
#
当 Http2Stream
已打开、已分配一个 id
且可用时,会发出 'ready'
事件。侦听器不期望任何参数。
事件:'timeout'
#
在未收到此 Http2Stream
的任何活动(持续时间以毫秒为单位,使用 http2stream.setTimeout()
设置)后,会发出 'timeout'
事件。其侦听器不期望任何参数。
事件:'trailers'
#
headers
<HTTP/2 Headers Object> 描述标头的对象flags
<number> 关联的数字标志
当收到与尾部标头字段关联的标头块时,会发出 'trailers'
事件。侦听器回调会传递 HTTP/2 标头对象 和与标头关联的标志。
如果在收到尾部标头之前调用了 http2stream.end()
且未读取或侦听传入数据,则可能不会发出此事件。
stream.on('trailers', (headers, flags) => {
console.log(headers);
});
事件:'wantTrailers'
#
当 Http2Stream
已将要发送到帧上的最后一个 DATA
帧排队,并且 Http2Stream
已准备好发送尾部标头时,会发出 'wantTrailers'
事件。在发起请求或响应时,必须设置 waitForTrailers
选项才能发出此事件。
http2stream.aborted
#
如果 Http2Stream
实例异常中止,则设置为 true
。设置后,将发出 'aborted'
事件。
http2stream.bufferSize
#
此属性显示当前缓冲以进行写入的字符数。有关详细信息,请参阅 net.Socket.bufferSize
。
http2stream.close(code[, callback])
#
code
<number> 标识错误代码的无符号 32 位整数。默认值:http2.constants.NGHTTP2_NO_ERROR
(0x00
)。callback
<Function> 注册为侦听'close'
事件的可选函数。
通过向连接的 HTTP/2 对等方发送 RST_STREAM
帧来关闭 Http2Stream
实例。
http2stream.closed
#
如果 Http2Stream
实例已关闭,则设置为 true
。
http2stream.destroyed
#
如果 Http2Stream
实例已销毁且不再可用,则设置为 true
。
http2stream.endAfterHeaders
#
如果在接收到的请求或响应 HEADERS 帧中设置了 END_STREAM
标志,则设置为 true
,表示不应接收其他数据,并且 Http2Stream
的可读端将关闭。
http2stream.id
#
此 Http2Stream
实例的数字流标识符。如果尚未分配流标识符,则设置为 undefined
。
http2stream.pending
#
如果 Http2Stream
实例尚未分配数字流标识符,则设置为 true
。
http2stream.priority(options)
#
options
<对象>
更新此 Http2Stream
实例的优先级。
http2stream.rstCode
#
当 Http2Stream
在从连接的对等方收到 RST_STREAM
帧、调用 http2stream.close()
或 http2stream.destroy()
后销毁时,设置为报告的 RST_STREAM
错误代码。如果 Http2Stream
尚未关闭,则为 undefined
。
http2stream.sentHeaders
#
包含为此 Http2Stream
发送的出站标头的对象。
http2stream.sentInfoHeaders
#
包含为此 Http2Stream
发送的出站信息(附加)标头的对象数组。
http2stream.sentTrailers
#
包含为此 HttpStream
发送的出站拖尾标头的对象。
http2stream.session
#
对拥有此 Http2Stream
的 Http2Session
实例的引用。在 Http2Stream
实例销毁后,该值将为 undefined
。
http2stream.setTimeout(msecs, callback)
#
msecs
<number>callback
<Function>
const http2 = require('node:http2');
const client = http2.connect('http://example.org:8000');
const { NGHTTP2_CANCEL } = http2.constants;
const req = client.request({ ':path': '/' });
// Cancel the stream if there's no activity after 5 seconds
req.setTimeout(5000, () => req.close(NGHTTP2_CANCEL));
http2stream.state
#
提供有关 Http2Stream
当前状态的各种信息。
- <对象>
localWindowSize
<number> 连接的对等方可以在不收到WINDOW_UPDATE
的情况下为此Http2Stream
发送的字节数。state
<number> 指示Http2Stream
当前底层状态的标志,由nghttp2
确定。localClose
<number> 如果此Http2Stream
已在本地关闭,则为1
。remoteClose
<number> 如果此Http2Stream
已在远程关闭,则为1
。sumDependencyWeight
<number> 依赖于此Http2Stream
的所有Http2Stream
实例的权重总和,如使用PRIORITY
帧指定的那样。weight
<number> 此Http2Stream
的优先级权重。
此 Http2Stream
的当前状态。
http2stream.sendTrailers(headers)
#
headers
<HTTP/2 标头对象>
向连接的 HTTP/2 对等方发送尾部 HEADERS
帧。此方法将导致 Http2Stream
立即关闭,并且只能在发出 'wantTrailers'
事件后调用。发送请求或发送响应时,必须设置 options.waitForTrailers
选项,以便在最终 DATA
帧后保持 Http2Stream
打开,以便可以发送尾部。
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond(undefined, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ xyz: 'abc' });
});
stream.end('Hello World');
});
HTTP/1 规范禁止尾部包含 HTTP/2 伪首部字段(例如 ':method'
、':path'
等)。
类:ClientHttp2Stream
#
ClientHttp2Stream
类是 Http2Stream
的扩展,专门用于 HTTP/2 客户端。客户端上的 Http2Stream
实例提供诸如 'response'
和 'push'
等事件,这些事件仅与客户端相关。
事件:'continue'
#
当服务器发送 100 Continue
状态时发出,通常是因为请求包含 Expect: 100-continue
。这是一条指令,客户端应发送请求正文。
事件:'headers'
#
headers
<HTTP/2 标头对象>flags
<number>
当为流接收到一个额外的头块时,将发出 'headers'
事件,例如当接收到一个 1xx
信息头块时。侦听器回调将传递 HTTP/2 头部对象 和与头部关联的标志。
stream.on('headers', (headers, flags) => {
console.log(headers);
});
事件:'push'
#
headers
<HTTP/2 标头对象>flags
<number>
当收到服务器推送流的响应头时,会发出 'push'
事件。侦听器回调会传递 HTTP/2 标头对象 和与标头关联的标志。
stream.on('push', (headers, flags) => {
console.log(headers);
});
事件:'response'
#
headers
<HTTP/2 标头对象>flags
<number>
当从连接的 HTTP/2 服务器接收到此流的响应 HEADERS
帧时,会发出 'response'
事件。侦听器将使用两个参数调用:一个包含已接收 HTTP/2 标头对象 的 Object
,以及与标头关联的标志。
const http2 = require('node:http2');
const client = http2.connect('https://127.0.0.1');
const req = client.request({ ':path': '/' });
req.on('response', (headers, flags) => {
console.log(headers[':status']);
});
类:ServerHttp2Stream
#
ServerHttp2Stream
类是 Http2Stream
的扩展,专门在 HTTP/2 服务器上使用。服务器上的 Http2Stream
实例提供了其他方法,例如 http2stream.pushStream()
和 http2stream.respond()
,这些方法仅与服务器相关。
http2stream.additionalHeaders(headers)
#
headers
<HTTP/2 标头对象>
向连接的 HTTP/2 对等方发送其他信息性 HEADERS
帧。
http2stream.headersSent
#
如果已发送标头,则为 true,否则为 false(只读)。
http2stream.pushAllowed
#
只读属性,映射到远程客户端最近的 SETTINGS
帧的 SETTINGS_ENABLE_PUSH
标志。如果远程对等方接受推送流,则为 true
,否则为 false
。同一 Http2Session
中的每个 Http2Stream
的设置都是相同的。
http2stream.pushStream(headers[, options], callback)
#
headers
<HTTP/2 标头对象>options
<对象>callback
<Function> 在启动推送流后调用的回调。err
<Error>pushStream
<ServerHttp2Stream> 返回的pushStream
对象。headers
<HTTP/2 Headers Object> 启动pushStream
的标头对象。
启动推送流。回调将使用为推送流创建的新 Http2Stream
实例(作为第二个参数传递)或作为第一个参数传递的 Error
调用。
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 });
stream.pushStream({ ':path': '/' }, (err, pushStream, headers) => {
if (err) throw err;
pushStream.respond({ ':status': 200 });
pushStream.end('some pushed data');
});
stream.end('some data');
});
在 HEADERS
帧中不允许设置推送流的权重。将 weight
值传递给 http2stream.priority
,并将 silent
选项设置为 true
,以启用并发流之间的服务器端带宽平衡。
不允许在推送流中调用 http2stream.pushStream()
,并且会引发错误。
http2stream.respond([headers[, options]])
#
headers
<HTTP/2 标头对象>options
<对象>
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 });
stream.end('some data');
});
启动响应。当设置 options.waitForTrailers
选项时,将在对要发送的有效负载数据的最后一个块排队后立即发出 'wantTrailers'
事件。然后可以使用 http2stream.sendTrailers()
方法将尾部标头字段发送给对等方。
当 options.waitForTrailers
被设置时,Http2Stream
在传输最终 DATA
帧时不会自动关闭。用户代码必须调用 http2stream.sendTrailers()
或 http2stream.close()
来关闭 Http2Stream
。
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 }, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
stream.end('some data');
});
http2stream.respondWithFD(fd[, headers[, options]])
#
fd
<number> | <FileHandle> 可读文件描述符。headers
<HTTP/2 标头对象>options
<对象>statCheck
<Function>waitForTrailers
<布尔值> 当true
时,在发送最终DATA
帧后,Http2Stream
将发出'wantTrailers'
事件。offset
<number> 开始读取的偏移位置。length
<number> 要从 fd 发送的数据量。
启动响应,其数据从给定的文件描述符中读取。不对给定的文件描述符执行验证。如果在尝试使用文件描述符读取数据时发生错误,则将使用标准 INTERNAL_ERROR
代码使用 RST_STREAM
帧关闭 Http2Stream
。
使用时,Http2Stream
对象的 Duplex
接口将自动关闭。
const http2 = require('node:http2');
const fs = require('node:fs');
const server = http2.createServer();
server.on('stream', (stream) => {
const fd = fs.openSync('/some/file', 'r');
const stat = fs.fstatSync(fd);
const headers = {
'content-length': stat.size,
'last-modified': stat.mtime.toUTCString(),
'content-type': 'text/plain; charset=utf-8',
};
stream.respondWithFD(fd, headers);
stream.on('close', () => fs.closeSync(fd));
});
可以指定可选的 options.statCheck
函数,以使用户代码有机会根据给定 fd 的 fs.Stat
详细信息设置其他内容标头。如果提供了 statCheck
函数,则 http2stream.respondWithFD()
方法将执行 fs.fstat()
调用以收集有关所提供文件描述符的详细信息。
offset
和 length
选项可用于将响应限制为特定的范围子集。例如,这可用于支持 HTTP 范围请求。
当流关闭时,文件描述符或 FileHandle
不会关闭,因此在不再需要时需要手动关闭它。不支持将同一个文件描述符并发用于多个流,并且可能导致数据丢失。支持在流完成后重新使用文件描述符。
如果设置了 options.waitForTrailers
选项,则在将要发送的有效负载数据的最后一个块排队后,将立即发出 'wantTrailers'
事件。然后,可以使用 http2stream.sendTrailers()
方法向对等方发送尾部标头字段。
如果设置了 options.waitForTrailers
,则在传输最终 DATA
帧时,Http2Stream
不会自动关闭。用户代码必须调用 http2stream.sendTrailers()
或 http2stream.close()
来关闭 Http2Stream
。
const http2 = require('node:http2');
const fs = require('node:fs');
const server = http2.createServer();
server.on('stream', (stream) => {
const fd = fs.openSync('/some/file', 'r');
const stat = fs.fstatSync(fd);
const headers = {
'content-length': stat.size,
'last-modified': stat.mtime.toUTCString(),
'content-type': 'text/plain; charset=utf-8',
};
stream.respondWithFD(fd, headers, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
stream.on('close', () => fs.closeSync(fd));
});
http2stream.respondWithFile(path[, headers[, options]])
#
path
<string> | <Buffer> | <URL>headers
<HTTP/2 标头对象>options
<对象>statCheck
<Function>onError
<Function> 在发送前出现错误时调用的回调函数。waitForTrailers
<布尔值> 当true
时,在发送最终DATA
帧后,Http2Stream
将发出'wantTrailers'
事件。offset
<number> 开始读取的偏移位置。length
<number> 要从 fd 发送的数据量。
将常规文件作为响应发送。path
必须指定一个常规文件,否则将在 Http2Stream
对象上发出 'error'
事件。
使用时,Http2Stream
对象的 Duplex
接口将自动关闭。
可以指定可选的 options.statCheck
函数,以便根据给定文件的 fs.Stat
详细信息,让用户代码有机会设置其他内容标头
如果在尝试读取文件数据时发生错误,则将使用标准 INTERNAL_ERROR
代码使用 RST_STREAM
帧关闭 Http2Stream
。如果定义了 onError
回调,则将调用它。否则,将销毁流。
使用文件路径的示例
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
function statCheck(stat, headers) {
headers['last-modified'] = stat.mtime.toUTCString();
}
function onError(err) {
// stream.respond() can throw if the stream has been destroyed by
// the other side.
try {
if (err.code === 'ENOENT') {
stream.respond({ ':status': 404 });
} else {
stream.respond({ ':status': 500 });
}
} catch (err) {
// Perform actual error handling.
console.error(err);
}
stream.end();
}
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain; charset=utf-8' },
{ statCheck, onError });
});
options.statCheck
函数也可以通过返回 false
来取消发送操作。例如,条件请求可以检查状态结果以确定文件是否已被修改,以便返回适当的 304
响应
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
function statCheck(stat, headers) {
// Check the stat here...
stream.respond({ ':status': 304 });
return false; // Cancel the send operation
}
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain; charset=utf-8' },
{ statCheck });
});
将自动设置 content-length
标头字段。
offset
和 length
选项可用于将响应限制为特定的范围子集。例如,这可用于支持 HTTP 范围请求。
options.onError
函数还可用于处理在启动文件传递之前可能发生的任何错误。默认行为是销毁流。
如果设置了 options.waitForTrailers
选项,则在将要发送的有效负载数据的最后一个块排队后,将立即发出 'wantTrailers'
事件。然后,可以使用 http2stream.sendTrailers()
方法向对等方发送尾部标头字段。
当 options.waitForTrailers
被设置时,Http2Stream
在传输最终 DATA
帧时不会自动关闭。用户代码必须调用 http2stream.sendTrailers()
或 http2stream.close()
来关闭 Http2Stream
。
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respondWithFile('/some/file',
{ 'content-type': 'text/plain; charset=utf-8' },
{ waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ ABC: 'some value to send' });
});
});
类:Http2Server
#
- 扩展:<net.Server>
Http2Server
实例是使用 http2.createServer()
函数创建的。Http2Server
类不会直接由 node:http2
模块导出。
事件:'checkContinue'
#
request
<http2.Http2ServerRequest>response
<http2.Http2ServerResponse>
如果注册了 'request'
侦听器或为 http2.createServer()
提供了回调函数,则每次收到带有 HTTP Expect: 100-continue
的请求时都会触发 'checkContinue'
事件。如果未侦听此事件,服务器将根据需要自动响应状态 100 Continue
。
处理此事件涉及调用 response.writeContinue()
(如果客户端应继续发送请求正文)或生成适当的 HTTP 响应(例如 400 Bad Request)(如果客户端不应继续发送请求正文)。
触发并处理此事件后,将不会触发 'request'
事件。
事件:'connection'
#
socket
<stream.Duplex>
当建立新的 TCP 流时,会触发此事件。socket
通常是 net.Socket
类型的对象。通常,用户不希望访问此事件。
用户还可以显式触发此事件,以将连接注入 HTTP 服务器。在这种情况下,可以传递任何 Duplex
流。
事件:'request'
#
request
<http2.Http2ServerRequest>response
<http2.Http2ServerResponse>
每次有请求时触发。每个会话可能有多个请求。请参见 兼容性 API。
事件:'session'
#
session
<ServerHttp2Session>
当 Http2Server
创建新的 Http2Session
时,会触发 'session'
事件。
事件:'sessionError'
#
error
<Error>session
<ServerHttp2Session>
当与 Http2Server
关联的 Http2Session
对象触发 'error'
事件时,会触发 'sessionError'
事件。
事件:'stream'
#
stream
<Http2Stream> 对流的引用headers
<HTTP/2 Headers Object> 描述标头的对象flags
<number> 关联的数字标志rawHeaders
<Array> 包含原始标头名称及其各自值的数组。
当与服务器关联的 Http2Session
发出 'stream'
事件时,会发出 'stream'
事件。
另请参阅 Http2Session
的 'stream'
事件。
const http2 = require('node:http2');
const {
HTTP2_HEADER_METHOD,
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
HTTP2_HEADER_CONTENT_TYPE,
} = http2.constants;
const server = http2.createServer();
server.on('stream', (stream, headers, flags) => {
const method = headers[HTTP2_HEADER_METHOD];
const path = headers[HTTP2_HEADER_PATH];
// ...
stream.respond({
[HTTP2_HEADER_STATUS]: 200,
[HTTP2_HEADER_CONTENT_TYPE]: 'text/plain; charset=utf-8',
});
stream.write('hello ');
stream.end('world');
});
事件:'timeout'
#
当服务器在使用 http2server.setTimeout()
设置的给定毫秒数内没有活动时,会发出 'timeout'
事件。默认值:0(无超时)
server.close([callback])
#
callback
<Function>
阻止服务器建立新会话。这并不会阻止创建新的请求流,因为 HTTP/2 会话具有持久性。要正常关闭服务器,请对所有活动会话调用 http2session.close()
。
如果提供了 callback
,则在所有活动会话关闭之前不会调用它,尽管服务器已经停止允许新会话。有关更多详细信息,请参阅 net.Server.close()
。
server[Symbol.asyncDispose]()
#
调用 server.close()
并返回一个在服务器关闭时兑现的 Promise。
server.setTimeout([msecs][, callback])
#
msecs
<number> 默认值:0(无超时)callback
<Function>- 返回:<Http2Server>
用于设置 http2 服务器请求的超时值,并在 Http2Server
在 msecs
毫秒后没有活动时设置一个回调函数。
给定的回调作为侦听器注册在 'timeout'
事件上。
如果 callback
不是函数,将抛出新的 ERR_INVALID_ARG_TYPE
错误。
server.timeout
#
- <number> 超时时间(毫秒)。默认值:0(无超时)
套接字被认为已超时之前的非活动毫秒数。
0
的值将禁用传入连接的超时行为。
套接字超时逻辑在连接时设置,因此更改此值仅影响与服务器的新连接,而不影响任何现有连接。
server.updateSettings([settings])
#
settings
<HTTP/2 设置对象>
用于使用提供的设置更新服务器。
对于无效的 settings
值,将抛出 ERR_HTTP2_INVALID_SETTING_VALUE
。
对于无效的 settings
参数,将抛出 ERR_INVALID_ARG_TYPE
。
类:Http2SecureServer
#
- 扩展:<tls.Server>
Http2SecureServer
的实例是使用 http2.createSecureServer()
函数创建的。Http2SecureServer
类不会直接由 node:http2
模块导出。
事件:'checkContinue'
#
request
<http2.Http2ServerRequest>response
<http2.Http2ServerResponse>
如果注册了 'request'
监听器或 http2.createSecureServer()
提供了回调函数,则每次收到带有 HTTP Expect: 100-continue
的请求时都会发出 'checkContinue'
事件。如果没有监听此事件,服务器将根据需要自动响应状态 100 Continue
。
处理此事件涉及调用 response.writeContinue()
(如果客户端应继续发送请求正文)或生成适当的 HTTP 响应(例如 400 Bad Request)(如果客户端不应继续发送请求正文)。
触发并处理此事件后,将不会触发 'request'
事件。
事件:'connection'
#
socket
<stream.Duplex>
在 TLS 握手开始之前,当建立新的 TCP 流时,将发出此事件。socket
通常是 net.Socket
类型的对象。通常,用户不会希望访问此事件。
用户还可以显式触发此事件,以将连接注入 HTTP 服务器。在这种情况下,可以传递任何 Duplex
流。
事件:'request'
#
request
<http2.Http2ServerRequest>response
<http2.Http2ServerResponse>
每次有请求时触发。每个会话可能有多个请求。请参见 兼容性 API。
事件:'session'
#
session
<ServerHttp2Session>
当 Http2SecureServer
创建新的 Http2Session
时,将发出 'session'
事件。
事件:'sessionError'
#
error
<Error>session
<ServerHttp2Session>
当与 Http2SecureServer
关联的 Http2Session
对象发出 'error'
事件时,将发出 'sessionError'
事件。
事件:'stream'
#
stream
<Http2Stream> 对流的引用headers
<HTTP/2 Headers Object> 描述标头的对象flags
<number> 关联的数字标志rawHeaders
<Array> 包含原始标头名称及其各自值的数组。
当与服务器关联的 Http2Session
发出 'stream'
事件时,会发出 'stream'
事件。
另请参阅 Http2Session
的 'stream'
事件。
const http2 = require('node:http2');
const {
HTTP2_HEADER_METHOD,
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
HTTP2_HEADER_CONTENT_TYPE,
} = http2.constants;
const options = getOptionsSomehow();
const server = http2.createSecureServer(options);
server.on('stream', (stream, headers, flags) => {
const method = headers[HTTP2_HEADER_METHOD];
const path = headers[HTTP2_HEADER_PATH];
// ...
stream.respond({
[HTTP2_HEADER_STATUS]: 200,
[HTTP2_HEADER_CONTENT_TYPE]: 'text/plain; charset=utf-8',
});
stream.write('hello ');
stream.end('world');
});
事件:'timeout'
#
当服务器在使用 http2secureServer.setTimeout()
设置的给定毫秒数内没有活动时,将发出 'timeout'
事件。默认值:2 分钟。
事件:'unknownProtocol'
#
socket
<stream.Duplex>
当连接客户端未能协商允许的协议(即 HTTP/2 或 HTTP/1.1)时,将发出 'unknownProtocol'
事件。事件处理程序接收用于处理的套接字。如果未为该事件注册侦听器,则终止连接。可以使用传递给 http2.createSecureServer()
的 'unknownProtocolTimeout'
选项指定超时。
在早期版本的 Node.js 中,如果 allowHTTP1
为 false
,并且在 TLS 握手期间,客户端不发送 ALPN 扩展或发送不包含 HTTP/2 (h2
) 的 ALPN 扩展,则会发出此事件。较新版本的 Node.js 仅在 allowHTTP1
为 false
且客户端不发送 ALPN 扩展时才会发出此事件。如果客户端发送不包含 HTTP/2(或 HTTP/1.1,如果 allowHTTP1
为 true
)的 ALPN 扩展,则 TLS 握手将失败,并且不会建立安全连接。
请参阅 兼容性 API。
server.close([callback])
#
callback
<Function>
阻止服务器建立新会话。这并不会阻止创建新的请求流,因为 HTTP/2 会话具有持久性。要正常关闭服务器,请对所有活动会话调用 http2session.close()
。
如果提供了 callback
,则在所有活动会话关闭之前不会调用它,尽管服务器已经停止允许新的会话。有关更多详细信息,请参阅 tls.Server.close()
。
server.setTimeout([msecs][, callback])
#
msecs
<number> 默认值:120000
(2 分钟)callback
<Function>- 返回:<Http2SecureServer>
用于设置 http2 安全服务器请求的超时值,并在 Http2SecureServer
在 msecs
毫秒后没有活动时设置一个回调函数。
给定的回调作为侦听器注册在 'timeout'
事件上。
如果 callback
不是函数,将抛出新的 ERR_INVALID_ARG_TYPE
错误。
server.timeout
#
- <number> 超时时间(毫秒)。默认值:0(无超时)
套接字被认为已超时之前的非活动毫秒数。
0
的值将禁用传入连接的超时行为。
套接字超时逻辑在连接时设置,因此更改此值仅影响与服务器的新连接,而不影响任何现有连接。
server.updateSettings([settings])
#
settings
<HTTP/2 设置对象>
用于使用提供的设置更新服务器。
对于无效的 settings
值,将抛出 ERR_HTTP2_INVALID_SETTING_VALUE
。
对于无效的 settings
参数,将抛出 ERR_INVALID_ARG_TYPE
。
http2.createServer([options][, onRequestHandler])
#
options
<对象>maxDeflateDynamicTableSize
<number> 设置用于压缩标头字段的最大动态表大小。默认值:4Kib
。maxSettings
<number> 设置每个SETTINGS
帧的最大设置条目数。允许的最小值为1
。默认值:32
。maxSessionMemory
<number> 设置Http2Session
允许使用的最大内存。该值以兆字节数表示,例如1
等于 1 兆字节。允许的最小值为1
。这是一个基于信用的限制,现有的Http2Stream
可能导致超出此限制,但在此限制被超出时会拒绝新的Http2Stream
实例。当前的Http2Stream
会话数、标头压缩表的当前内存使用量、当前排队准备发送的数据以及未确认的PING
和SETTINGS
帧都计入当前限制。默认值:10
。maxHeaderListPairs
<number> 设置标头条目的最大数量。这类似于node:http
模块中的server.maxHeadersCount
或request.maxHeadersCount
。最小值为4
。默认值:128
。maxOutstandingPings
<number> 设置未确认的未完成 ping 的最大数量。默认值:10
。maxSendHeaderBlockLength
<number> 设置序列化压缩标头块允许的最大大小。尝试发送超过此限制的标头将导致发出'frameError'
事件,并且流将被关闭并销毁。虽然这将允许的最大大小设置为整个标头块,但nghttp2
(内部 http2 库)对每个解压缩的键/值对的限制为65536
。paddingStrategy
<number> 用于确定用于HEADERS
和DATA
帧的填充量。默认值:http2.constants.PADDING_STRATEGY_NONE
。值可以是http2.constants.PADDING_STRATEGY_NONE
:不应用填充。http2.constants.PADDING_STRATEGY_MAX
:应用由内部实现确定的最大填充量。http2.constants.PADDING_STRATEGY_ALIGNED
:尝试应用足够的填充以确保总帧长度(包括 9 字节标头)是 8 的倍数。对于每个帧,都有一个允许的最大填充字节数,该字节数由当前流控制状态和设置确定。如果此最大值小于确保对齐所需的计算量,则使用最大值,并且总帧长度不一定在 8 字节处对齐。
peerMaxConcurrentStreams
<number> 设置远程对等方的最大并发流数,就好像已收到SETTINGS
帧一样。如果远程对等方为maxConcurrentStreams
设置了自己的值,则将被覆盖。默认值:100
。maxSessionInvalidFrames
<整数> 设置在关闭会话之前容忍的无效帧的最大数量。默认值:1000
。maxSessionRejectedStreams
<整数> 设置在关闭会话之前容忍的创建时被拒绝的流的最大数量。每个拒绝与一个NGHTTP2_ENHANCE_YOUR_CALM
错误相关联,该错误应告知对等方不要再打开任何流,因此继续打开流被视为行为不当的对等方的标志。默认值:100
。settings
<HTTP/2 设置对象> 连接后发送给远程对等方的初始设置。remoteCustomSettings
<数组> 整数值的数组确定设置类型,这些类型包含在接收到的 remoteSettings 的CustomSettings
属性中。有关允许的设置类型的更多信息,请参阅Http2Settings
对象的CustomSettings
属性。Http1IncomingMessage
<http.IncomingMessage> 指定用于 HTTP/1 回退的IncomingMessage
类。对于扩展原始http.IncomingMessage
很有用。默认值:http.IncomingMessage
。Http1ServerResponse
<http.ServerResponse> 指定用于 HTTP/1 回退的ServerResponse
类。对于扩展原始http.ServerResponse
很有用。默认值:http.ServerResponse
。Http2ServerRequest
<http2.Http2ServerRequest> 指定要使用的Http2ServerRequest
类。对于扩展原始Http2ServerRequest
很有用。默认值:Http2ServerRequest
。Http2ServerResponse
<http2.Http2ServerResponse> 指定要使用的Http2ServerResponse
类。对于扩展原始Http2ServerResponse
很有用。默认值:Http2ServerResponse
。unknownProtocolTimeout
<数字> 指定服务器在发出'unknownProtocol'
时应等待的超时时间(以毫秒为单位)。如果那时套接字尚未被销毁,服务器将销毁它。默认值:10000
。- ...: 任何
net.createServer()
选项都可以提供。
onRequestHandler
<Function> 请参阅 兼容性 API- 返回:<Http2Server>
返回一个 net.Server
实例,该实例创建并管理 Http2Session
实例。
由于没有已知的浏览器支持 未加密的 HTTP/2,因此在与浏览器客户端通信时,必须使用 http2.createSecureServer()
。
const http2 = require('node:http2');
// Create an unencrypted HTTP/2 server.
// Since there are no browsers known that support
// unencrypted HTTP/2, the use of `http2.createSecureServer()`
// is necessary when communicating with browser clients.
const server = http2.createServer();
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8000);
http2.createSecureServer(options[, onRequestHandler])
#
options
<对象>allowHTTP1
<boolean> 当设置为true
时,不支持 HTTP/2 的传入客户端连接将降级为 HTTP/1.x。请参阅'unknownProtocol'
事件。请参阅 ALPN 协商。默认值:false
。maxDeflateDynamicTableSize
<number> 设置用于压缩标头字段的最大动态表大小。默认值:4Kib
。maxSettings
<number> 设置每个SETTINGS
帧的最大设置条目数。允许的最小值为1
。默认值:32
。maxSessionMemory
<number> 设置Http2Session
允许使用的最大内存。该值以兆字节数表示,例如1
等于 1 兆字节。允许的最小值为1
。这是一个基于信用的限制,现有的Http2Stream
可能导致超出此限制,但在此限制被超出时会拒绝新的Http2Stream
实例。当前的Http2Stream
会话数、标头压缩表的当前内存使用量、当前排队准备发送的数据以及未确认的PING
和SETTINGS
帧都计入当前限制。默认值:10
。maxHeaderListPairs
<number> 设置标头条目的最大数量。这类似于node:http
模块中的server.maxHeadersCount
或request.maxHeadersCount
。最小值为4
。默认值:128
。maxOutstandingPings
<number> 设置未确认的未完成 ping 的最大数量。默认值:10
。maxSendHeaderBlockLength
<number> 设置序列化、压缩的标头块允许的最大大小。尝试发送超过此限制的标头将导致发出'frameError'
事件,并且流将被关闭并销毁。paddingStrategy
<number> 用于确定对HEADERS
和DATA
帧使用填充量的方法。默认值:http2.constants.PADDING_STRATEGY_NONE
。值可以是http2.constants.PADDING_STRATEGY_NONE
:不应用填充。http2.constants.PADDING_STRATEGY_MAX
:应用由内部实现确定的最大填充量。http2.constants.PADDING_STRATEGY_ALIGNED
:尝试应用足够的填充以确保总帧长度(包括 9 字节标头)是 8 的倍数。对于每个帧,都有一个允许的最大填充字节数,该字节数由当前流控制状态和设置确定。如果此最大值小于确保对齐所需的计算量,则使用最大值,并且总帧长度不一定在 8 字节处对齐。
peerMaxConcurrentStreams
<number> 设置远程对等方的最大并发流数,就好像已收到SETTINGS
帧一样。如果远程对等方为maxConcurrentStreams
设置了自己的值,则将被覆盖。默认值:100
。maxSessionInvalidFrames
<整数> 设置在关闭会话之前容忍的无效帧的最大数量。默认值:1000
。maxSessionRejectedStreams
<整数> 设置在关闭会话之前容忍的创建时被拒绝的流的最大数量。每个拒绝与一个NGHTTP2_ENHANCE_YOUR_CALM
错误相关联,该错误应告知对等方不要再打开任何流,因此继续打开流被视为行为不当的对等方的标志。默认值:100
。settings
<HTTP/2 设置对象> 连接后发送给远程对等方的初始设置。remoteCustomSettings
<Array> 整数值数组确定设置类型,这些类型包含在接收到的 remoteSettings 的customSettings
属性中。有关允许的设置类型,请参阅Http2Settings
对象的customSettings
属性以获取更多信息。- ...: 可以提供任何
tls.createServer()
选项。对于服务器,通常需要身份选项(pfx
或key
/cert
)。 origins
<string[]> 在创建新的服务器Http2Session
后立即在ORIGIN
帧中发送的原点字符串数组。unknownProtocolTimeout
<number> 指定服务器在发出'unknownProtocol'
事件时应等待的超时时间(以毫秒为单位)。如果到那时套接字尚未销毁,服务器将销毁它。默认值:10000
。
onRequestHandler
<Function> 请参阅 兼容性 API- 返回:<Http2SecureServer>
返回一个 tls.Server
实例,用于创建和管理 Http2Session
实例。
const http2 = require('node:http2');
const fs = require('node:fs');
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem'),
};
// Create a secure HTTP/2 server
const server = http2.createSecureServer(options);
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200,
});
stream.end('<h1>Hello World</h1>');
});
server.listen(8443);
http2.connect(authority[, options][, listener])
#
authority
<string> | <URL> 要连接到的远程 HTTP/2 服务器。这必须采用最小有效 URL 的形式,其中包含http://
或https://
前缀、主机名和 IP 端口(如果使用非默认端口)。URL 中的用户信息(用户 ID 和密码)、路径、查询字符串和片段详细信息将被忽略。options
<对象>maxDeflateDynamicTableSize
<number> 设置用于压缩标头字段的最大动态表大小。默认值:4Kib
。maxSettings
<number> 设置每个SETTINGS
帧的最大设置条目数。允许的最小值为1
。默认值:32
。maxSessionMemory
<number> 设置Http2Session
允许使用的最大内存。该值以兆字节数表示,例如1
等于 1 兆字节。允许的最小值为1
。这是一个基于信用的限制,现有的Http2Stream
可能导致超出此限制,但在此限制被超出时会拒绝新的Http2Stream
实例。当前的Http2Stream
会话数、标头压缩表的当前内存使用量、当前排队准备发送的数据以及未确认的PING
和SETTINGS
帧都计入当前限制。默认值:10
。maxHeaderListPairs
<number> 设置标头项的最大数量。这类似于node:http
模块中的server.maxHeadersCount
或request.maxHeadersCount
。最小值为1
。默认值:128
。maxOutstandingPings
<number> 设置未确认的未完成 ping 的最大数量。默认值:10
。maxReservedRemoteStreams
<number> 设置客户端在任何给定时间接受的保留推送流的最大数量。一旦当前保留的推送流的当前数量超过此限制,服务器发送的新推送流将自动被拒绝。允许的最小值为 0。允许的最大值为 232-1。负值将此选项设置为允许的最大值。默认值:200
。maxSendHeaderBlockLength
<number> 设置序列化、压缩的标头块允许的最大大小。尝试发送超过此限制的标头将导致发出'frameError'
事件,并且流将被关闭并销毁。paddingStrategy
<number> 用于确定对HEADERS
和DATA
帧使用填充量的方法。默认值:http2.constants.PADDING_STRATEGY_NONE
。值可以是http2.constants.PADDING_STRATEGY_NONE
:不应用填充。http2.constants.PADDING_STRATEGY_MAX
:应用由内部实现确定的最大填充量。http2.constants.PADDING_STRATEGY_ALIGNED
:尝试应用足够的填充以确保总帧长度(包括 9 字节标头)是 8 的倍数。对于每个帧,都有一个允许的最大填充字节数,该字节数由当前流控制状态和设置确定。如果此最大值小于确保对齐所需的计算量,则使用最大值,并且总帧长度不一定在 8 字节处对齐。
peerMaxConcurrentStreams
<number> 设置远程对等方的最大并发流数,就好像已收到SETTINGS
帧一样。如果远程对等方为maxConcurrentStreams
设置了自己的值,则将被覆盖。默认值:100
。protocol
<string> 要连接的协议,如果没有在authority
中设置。值可以是'http:'
或'https:'
。默认值:'https:'
settings
<HTTP/2 设置对象> 连接后发送给远程对等方的初始设置。remoteCustomSettings
<数组> 整数值的数组确定设置类型,这些类型包含在接收到的 remoteSettings 的CustomSettings
属性中。有关允许的设置类型的更多信息,请参阅Http2Settings
对象的CustomSettings
属性。createConnection
<Function> 可选回调,接收传递给connect
的URL
实例和options
对象,并返回任何Duplex
流,用作此会话的连接。- ...: 可以提供任何
net.connect()
或tls.connect()
选项。 unknownProtocolTimeout
<number> 指定服务器在发出'unknownProtocol'
事件时应等待的超时时间(以毫秒为单位)。如果到那时套接字尚未销毁,服务器将销毁它。默认值:10000
。
listener
<Function> 将作为'connect'
事件的一次性侦听器进行注册。- 返回:<ClientHttp2Session>
返回一个 ClientHttp2Session
实例。
const http2 = require('node:http2');
const client = http2.connect('https://127.0.0.1:1234');
/* Use the client */
client.close();
http2.constants
#
RST_STREAM
和 GOAWAY
的错误代码#
值 | 名称 | 常量 |
---|---|---|
0x00 | 无错误 | http2.constants.NGHTTP2_NO_ERROR |
0x01 | 协议错误 | http2.constants.NGHTTP2_PROTOCOL_ERROR |
0x02 | 内部错误 | http2.constants.NGHTTP2_INTERNAL_ERROR |
0x03 | 流控错误 | http2.constants.NGHTTP2_FLOW_CONTROL_ERROR |
0x04 | 设置超时 | http2.constants.NGHTTP2_SETTINGS_TIMEOUT |
0x05 | 流已关闭 | http2.constants.NGHTTP2_STREAM_CLOSED |
0x06 | 帧大小错误 | http2.constants.NGHTTP2_FRAME_SIZE_ERROR |
0x07 | 已拒绝流 | http2.constants.NGHTTP2_REFUSED_STREAM |
0x08 | 取消 | http2.constants.NGHTTP2_CANCEL |
0x09 | 压缩错误 | http2.constants.NGHTTP2_COMPRESSION_ERROR |
0x0a | 连接错误 | http2.constants.NGHTTP2_CONNECT_ERROR |
0x0b | 保持冷静 | http2.constants.NGHTTP2_ENHANCE_YOUR_CALM |
0x0c | 安全性不足 | http2.constants.NGHTTP2_INADEQUATE_SECURITY |
0x0d | 需要 HTTP/1.1 | http2.constants.NGHTTP2_HTTP_1_1_REQUIRED |
当服务器在使用 http2server.setTimeout()
设置的给定毫秒数内没有活动时,将发出 'timeout'
事件。
http2.getDefaultSettings()
#
返回一个包含 Http2Session
实例的默认设置的对象。此方法每次调用时都会返回一个新对象实例,因此返回的实例可以安全修改以供使用。
http2.getPackedSettings([settings])
#
settings
<HTTP/2 设置对象>- 返回:<Buffer>
返回一个 Buffer
实例,其中包含指定在 HTTP/2 规范中的给定 HTTP/2 设置的序列化表示形式。这旨在与 HTTP2-Settings
头字段一起使用。
const http2 = require('node:http2');
const packed = http2.getPackedSettings({ enablePush: false });
console.log(packed.toString('base64'));
// Prints: AAIAAAAA
http2.getUnpackedSettings(buf)
#
buf
<Buffer> | <TypedArray> 已打包的设置。- 返回:<HTTP/2 设置对象>
返回一个 HTTP/2 设置对象,其中包含由 http2.getPackedSettings()
生成的给定 Buffer
中反序列化的设置。
http2.performServerHandshake(socket[, options])
#
socket
<stream.Duplex>options
<对象>- ...: 可以提供任何
http2.createServer()
选项。
- ...: 可以提供任何
- 返回:<ServerHttp2Session>
从现有套接字创建 HTTP/2 服务器会话。
http2.sensitiveHeaders
#
可以将此符号作为 HTTP/2 标头对象上的一个属性设置,其中包含一个数组值,以提供被认为是敏感的标头列表。有关更多详细信息,请参阅 敏感标头。
标头对象#
标头表示为 JavaScript 对象上的自有属性。属性键将序列化为小写。属性值应为字符串(如果不是,则会强制转换为字符串)或字符串的 Array
(以便每个标头字段发送多个值)。
const headers = {
':status': '200',
'content-type': 'text-plain',
'ABC': ['has', 'more', 'than', 'one', 'value'],
};
stream.respond(headers);
传递给回调函数的标头对象将具有 null
原型。这意味着正常的 JavaScript 对象方法(例如 Object.prototype.toString()
和 Object.prototype.hasOwnProperty()
)将不起作用。
对于传入标头
:status
标头转换为number
。:status
、:method
、:authority
、:scheme
、:path
、:protocol
、age
、authorization
、access-control-allow-credentials
、access-control-max-age
、access-control-request-method
、content-encoding
、content-language
、content-length
、content-location
、content-md5
、content-range
、content-type
、date
、dnt
、etag
、expires
、from
、host
、if-match
、if-modified-since
、if-none-match
、if-range
、if-unmodified-since
、last-modified
、location
、max-forwards
、proxy-authorization
、range
、referer
、retry-after
、tk
、upgrade-insecure-requests
、user-agent
或x-content-type-options
的重复项将被丢弃。set-cookie
始终是一个数组。重复项将添加到数组中。- 对于重复的
cookie
头,值将用“;”连接起来。 - 对于所有其他头,值将用“,”连接起来。
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream, headers) => {
console.log(headers[':path']);
console.log(headers.ABC);
});
敏感头#
HTTP2 头可以标记为敏感,这意味着 HTTP/2 头压缩算法永远不会对其编制索引。对于熵值低且攻击者可能认为有价值的头值(例如 Cookie
或 Authorization
),这可能很有意义。要实现此目的,请将头名称作为数组添加到 [http2.sensitiveHeaders]
属性中
const headers = {
':status': '200',
'content-type': 'text-plain',
'cookie': 'some-cookie',
'other-sensitive-header': 'very secret data',
[http2.sensitiveHeaders]: ['cookie', 'other-sensitive-header'],
};
stream.respond(headers);
对于某些头(例如 Authorization
和较短的 Cookie
头),此标志会自动设置。
此属性也会为接收到的头设置。它将包含所有标记为敏感的头名称,包括自动标记为敏感的头。
设置对象#
http2.getDefaultSettings()
、http2.getPackedSettings()
、http2.createServer()
、http2.createSecureServer()
、http2session.settings()
、http2session.localSettings
和 http2session.remoteSettings
API 要么返回要么接收一个对象作为输入,该对象定义了 Http2Session
对象的配置设置。这些对象是包含以下属性的普通 JavaScript 对象。
headerTableSize
<number> 指定用于头压缩的最大字节数。允许的最小值为 0。允许的最大值为 232-1。默认值:4096
。enablePush
<boolean> 如果允许在Http2Session
实例上使用 HTTP/2 推送流,则指定true
。默认值:true
。initialWindowSize
<number> 指定流级流控制中发送方的初始窗口大小(以字节为单位)。允许的最小值为 0。允许的最大值为 232-1。默认值:65535
。maxFrameSize
<number> 指定最大帧有效负载的大小(以字节为单位)。允许的最小值为 16,384。允许的最大值为 224-1。默认值:16384
。maxConcurrentStreams
<number> 指定允许在Http2Session
上的最大并发流数。没有默认值,至少在理论上,在Http2Session
中任何给定时间可同时打开 232-1 个流。最小值为 0。允许的最大值为 232-1。默认值:4294967295
。maxHeaderListSize
<number> 指定将接受的头列表的最大大小(未压缩八位字节)。允许的最小值为 0。允许的最大值为 232-1。默认值:65535
。maxHeaderSize
<number>maxHeaderListSize
的别名。enableConnectProtocol
<boolean> 如果 RFC 8441 定义的“扩展连接协议”已启用,则指定true
。此设置仅在由服务器发送时才有意义。一旦为给定的Http2Session
启用了enableConnectProtocol
设置,则无法禁用它。默认值:false
。customSettings
<Object> 指定其他设置,但尚未在 node 和底层库中实现。该对象的键定义了设置类型的数值(如 [RFC 7540] 建立的“HTTP/2 设置”注册表中定义的那样),而值则定义了设置的实际数值。设置类型必须是介于 1 到 2^16-1 之间的整数。它不应是 node 已经处理的设置类型,即当前应大于 6,尽管这不是错误。值必须是介于 0 到 2^32-1 之间的无符号整数。目前,最多支持 10 个自定义设置。它仅支持发送设置,或接收在服务器或客户端对象的remoteCustomSettings
选项中指定的设置值。请勿将设置 ID 的customSettings
机制与本机处理的设置的接口混淆,以防将来某个 node 版本本机支持某个设置。
设置对象上的所有其他属性都将被忽略。
错误处理#
使用 node:http2
模块时可能会出现多种类型的错误条件
当传入不正确的参数、选项或设置值时,将发生验证错误。这些错误将始终由同步 throw
报告。
当在不正确的时间尝试执行操作时(例如,尝试在流关闭后向流发送数据),将发生状态错误。这些错误将通过同步 throw
或通过 Http2Stream
、Http2Session
或 HTTP/2 服务器对象上的 'error'
事件报告,具体取决于错误发生的位置和时间。
当 HTTP/2 会话意外失败时,将发生内部错误。这些错误将通过 Http2Session
或 HTTP/2 服务器对象上的 'error'
事件报告。
当违反各种 HTTP/2 协议约束时,将发生协议错误。这些错误将通过同步 throw
或通过 Http2Stream
、Http2Session
或 HTTP/2 服务器对象上的 'error'
事件报告,具体取决于错误发生的位置和时间。
标头名称和值中的无效字符处理#
与 HTTP/1 实现相比,HTTP/2 实现对 HTTP 标头名称和值中的无效字符应用了更严格的处理。
标头字段名称不区分大小写,并且通过网络严格作为小写字符串传输。Node.js 提供的 API 允许将标头名称设置为混合大小写字符串(例如 Content-Type
),但在传输时会将其转换为小写(例如 content-type
)。
标头字段名称只能包含以下一个或多个 ASCII 字符:a
-z
、A
-Z
、0
-9
、!
、#
、$
、%
、&
、'
、*
、+
、-
、.
、^
、_
、`
(反引号)、|
和 ~
。
在 HTTP 标头字段名称中使用无效字符将导致流关闭,并报告协议错误。
标头字段值处理得更宽松,但不应包含换行符或回车符,并且应根据 HTTP 规范的要求限制为 US-ASCII 字符。
客户端上的推送流#
要在客户端接收推送流,请为 ClientHttp2Session
上的 'stream'
事件设置一个侦听器
const http2 = require('node:http2');
const client = http2.connect('https://127.0.0.1');
client.on('stream', (pushedStream, requestHeaders) => {
pushedStream.on('push', (responseHeaders) => {
// Process response headers
});
pushedStream.on('data', (chunk) => { /* handle pushed data */ });
});
const req = client.request({ ':path': '/' });
支持 CONNECT
方法#
CONNECT
方法用于允许将 HTTP/2 服务器用作 TCP/IP 连接的代理。
简单的 TCP 服务器
const net = require('node:net');
const server = net.createServer((socket) => {
let name = '';
socket.setEncoding('utf8');
socket.on('data', (chunk) => name += chunk);
socket.on('end', () => socket.end(`hello ${name}`));
});
server.listen(8000);
HTTP/2 CONNECT 代理
const http2 = require('node:http2');
const { NGHTTP2_REFUSED_STREAM } = http2.constants;
const net = require('node:net');
const proxy = http2.createServer();
proxy.on('stream', (stream, headers) => {
if (headers[':method'] !== 'CONNECT') {
// Only accept CONNECT requests
stream.close(NGHTTP2_REFUSED_STREAM);
return;
}
const auth = new URL(`tcp://${headers[':authority']}`);
// It's a very good idea to verify that hostname and port are
// things this proxy should be connecting to.
const socket = net.connect(auth.port, auth.hostname, () => {
stream.respond();
socket.pipe(stream);
stream.pipe(socket);
});
socket.on('error', (error) => {
stream.close(http2.constants.NGHTTP2_CONNECT_ERROR);
});
});
proxy.listen(8001);
HTTP/2 CONNECT 客户端
const http2 = require('node:http2');
const client = http2.connect('https://127.0.0.1:8001');
// Must not specify the ':path' and ':scheme' headers
// for CONNECT requests or an error will be thrown.
const req = client.request({
':method': 'CONNECT',
':authority': 'localhost:8000',
});
req.on('response', (headers) => {
console.log(headers[http2.constants.HTTP2_HEADER_STATUS]);
});
let data = '';
req.setEncoding('utf8');
req.on('data', (chunk) => data += chunk);
req.on('end', () => {
console.log(`The server says: ${data}`);
client.close();
});
req.end('Jane');
扩展的 CONNECT
协议#
RFC 8441 定义了 HTTP/2 的“扩展 CONNECT 协议”扩展,该扩展可用于使用 CONNECT
方法引导 Http2Stream
的使用,作为其他通信协议(如 WebSockets)的隧道。
HTTP/2 服务器通过使用 enableConnectProtocol
设置来启用扩展 CONNECT 协议的使用
const http2 = require('node:http2');
const settings = { enableConnectProtocol: true };
const server = http2.createServer({ settings });
一旦客户端从服务器收到 SETTINGS
帧,表明可以使用扩展 CONNECT,它就可以发送使用 ':protocol'
HTTP/2 伪标头的 CONNECT
请求
const http2 = require('node:http2');
const client = http2.connect('https://127.0.0.1:8080');
client.on('remoteSettings', (settings) => {
if (settings.enableConnectProtocol) {
const req = client.request({ ':method': 'CONNECT', ':protocol': 'foo' });
// ...
}
});
兼容性 API#
兼容性 API 的目标是在使用 HTTP/2 时提供类似于 HTTP/1 的开发人员体验,从而可以开发同时支持 HTTP/1 和 HTTP/2 的应用程序。此 API 仅针对 HTTP/1 的公共 API。但是,许多模块使用内部方法或状态,并且这些方法或状态不受支持,因为这是完全不同的实现。
以下示例使用兼容性 API 创建 HTTP/2 服务器
const http2 = require('node:http2');
const server = http2.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('ok');
});
为了创建混合的 HTTPS 和 HTTP/2 服务器,请参阅 ALPN 协商 部分。不支持从非 TLS HTTP/1 服务器升级。
HTTP/2 兼容性 API 由 Http2ServerRequest
和 Http2ServerResponse
组成。它们旨在与 HTTP/1 的 API 兼容,但它们不会隐藏协议之间的差异。例如,HTTP 代码的状态消息被忽略。
ALPN 协商#
ALPN 协商允许在同一套接字上同时支持 HTTPS 和 HTTP/2。req
和 res
对象可以是 HTTP/1 或 HTTP/2,并且应用程序必须限制自身使用 HTTP/1 的公共 API,并检测是否可以使用 HTTP/2 的更高级功能。
以下示例创建一个同时支持这两个协议的服务器
const { createSecureServer } = require('node:http2');
const { readFileSync } = require('node:fs');
const cert = readFileSync('./cert.pem');
const key = readFileSync('./key.pem');
const server = createSecureServer(
{ cert, key, allowHTTP1: true },
onRequest,
).listen(4443);
function onRequest(req, res) {
// Detects if it is a HTTPS request or HTTP/2
const { socket: { alpnProtocol } } = req.httpVersion === '2.0' ?
req.stream.session : req;
res.writeHead(200, { 'content-type': 'application/json' });
res.end(JSON.stringify({
alpnProtocol,
httpVersion: req.httpVersion,
}));
}
'request'
事件在 HTTPS 和 HTTP/2 上的工作方式相同。
类:http2.Http2ServerRequest
#
Http2ServerRequest
对象由 http2.Server
或 http2.SecureServer
创建,并作为 'request'
事件的第一个参数传递。它可用于访问请求状态、标头和数据。
事件:'aborted'
#
每当 Http2ServerRequest
实例在通信过程中异常中止时,都会发出 'aborted'
事件。
仅当 Http2ServerRequest
可写端尚未结束时,才会发出 'aborted'
事件。
事件:'close'
#
表示底层的 Http2Stream
已关闭。与 'end'
一样,此事件每个响应只发生一次。
request.aborted
#
如果请求已中止,则 request.aborted
属性将为 true
。
request.authority
#
请求授权伪标头字段。由于 HTTP/2 允许请求设置 :authority
或 host
,因此如果存在,此值将从 req.headers[':authority']
派生。否则,它将从 req.headers['host']
派生。
request.complete
#
如果请求已完成、中止或销毁,则 request.complete
属性将为 true
。
request.connection
#
request.socket
。参见 request.socket
。
request.destroy([error])
#
error
<Error>
在收到 Http2ServerRequest
的 Http2Stream
上调用 destroy()
。如果提供了 error
,则会发出 'error'
事件,并且 error
作为参数传递给事件上的任何侦听器。
如果流已销毁,则不执行任何操作。
request.headers
#
请求/响应头对象。
头名称和值的键值对。头名称采用小写形式。
// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*' }
console.log(request.headers);
参见 HTTP/2 头对象。
在 HTTP/2 中,请求路径、主机名、协议和方法表示为以 :
字符为前缀的特殊头(例如 ':path'
)。这些特殊头将包含在 request.headers
对象中。必须小心不要无意中修改这些特殊头,否则可能会出错。例如,从请求中删除所有头将导致出错
removeAllHeaders(request.headers);
assert(request.url); // Fails because the :path header has been removed
request.httpVersion
#
对于服务器请求,客户端发送的 HTTP 版本。对于客户端响应,连接到的服务器的 HTTP 版本。返回 '2.0'
。
此外,message.httpVersionMajor
是第一个整数,message.httpVersionMinor
是第二个整数。
request.method
#
请求方法(字符串)。只读。示例:'GET'
、'DELETE'
。
request.rawHeaders
#
完全按照接收到的方式列出的原始请求/响应头。
键和值在同一个列表中。它不是元组列表。因此,偶数偏移量是键值,奇数偏移量是关联的值。
标头名称未采用小写,且未合并重复项。
// Prints something like:
//
// [ '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);
request.rawTrailers
#
原始请求/响应拖尾键和值,完全按接收到的方式显示。仅在'end'
事件中填充。
request.scheme
#
请求方案伪标头字段,指示目标 URL 的方案部分。
request.setTimeout(msecs, callback)
#
msecs
<number>callback
<Function>- 返回:<http2.Http2ServerRequest>
将Http2Stream
的超时值设置为msecs
。如果提供了回调,则将其添加为响应对象上'timeout'
事件的侦听器。
如果未向请求、响应或服务器添加'timeout'
侦听器,则Http2Stream
将在超时时销毁。如果已将处理程序分配给请求、响应或服务器的'timeout'
事件,则必须显式处理超时的套接字。
request.socket
#
返回一个Proxy
对象,该对象充当net.Socket
(或tls.TLSSocket
),但会根据 HTTP/2 逻辑应用 getter、setter 和方法。
destroyed
、readable
和writable
属性将从request.stream
中检索并设置到request.stream
上。
destroy
、emit
、end
、on
和once
方法将在request.stream
上调用。
setTimeout
方法将在request.stream.session
上调用。
pause
、read
、resume
和write
将抛出一个错误,错误代码为ERR_HTTP2_NO_SOCKET_MANIPULATION
。有关更多信息,请参阅Http2Session
和套接字。
所有其他交互都将直接路由到套接字。在有 TLS 支持的情况下,请使用request.socket.getPeerCertificate()
获取客户端的身份验证详细信息。
request.stream
#
支持请求的Http2Stream
对象。
request.trailers
#
请求/响应尾部对象。仅在'end'
事件中填充。
request.url
#
请求 URL 字符串。它仅包含实际 HTTP 请求中存在的 URL。如果请求为
GET /status?name=ryan HTTP/1.1
Accept: text/plain
则request.url
将为
'/status?name=ryan'
要将 url 解析为其各个部分,可以使用new URL()
$ node
> new URL('/status?name=ryan', 'http://example.com')
URL {
href: 'http://example.com/status?name=ryan',
origin: 'http://example.com',
protocol: 'http:',
username: '',
password: '',
host: 'example.com',
hostname: 'example.com',
port: '',
pathname: '/status',
search: '?name=ryan',
searchParams: URLSearchParams { 'name' => 'ryan' },
hash: ''
}
类:http2.Http2ServerResponse
#
- 扩展:<Stream>
此对象由 HTTP 服务器在内部创建,而不是由用户创建。它作为第二个参数传递给'request'
事件。
事件:'close'
#
表示在调用 response.end()
或能够刷新之前,底层Http2Stream
已终止。
事件:'finish'
#
在发送响应时发出。更具体地说,当响应头和正文的最后一个部分已移交给 HTTP/2 多路复用以通过网络传输时,会发出此事件。这并不意味着客户端已经收到任何内容。
在此事件之后,响应对象上将不会再发出更多事件。
response.addTrailers(headers)
#
headers
<Object>
此方法将 HTTP 尾部头(一个头,但位于消息末尾)添加到响应中。
尝试设置包含无效字符的头字段名或值将导致抛出TypeError
。
response.appendHeader(name, value)
#
name
<string>value
<string> | <string[]>
将单个头值附加到头对象。
如果该值是一个数组,则这等同于多次调用此方法。
如果标题没有之前的任何值,则这等同于调用 response.setHeader()
。
尝试设置包含无效字符的头字段名或值将导致抛出TypeError
。
// Returns headers including "set-cookie: a" and "set-cookie: b"
const server = http2.createServer((req, res) => {
res.setHeader('set-cookie', 'a');
res.appendHeader('set-cookie', 'b');
res.writeHead(200);
res.end('ok');
});
response.connection
#
response.socket
。参见 response.socket
。
response.createPushResponse(headers, callback)
#
headers
<HTTP/2 Headers Object> 描述标头的对象callback
<Function> 一旦http2stream.pushStream()
完成,或者当尝试创建推入的Http2Stream
失败或被拒绝,或者在调用http2stream.pushStream()
方法之前Http2ServerRequest
的状态被关闭时调用err
<Error>res
<http2.Http2ServerResponse> 新创建的Http2ServerResponse
对象
使用给定的标头调用 http2stream.pushStream()
,并将给定的 Http2Stream
包装在成功时的回调参数中,作为新创建的 Http2ServerResponse
。当 Http2ServerRequest
关闭时,回调将使用错误 ERR_HTTP2_INVALID_STREAM
调用。
response.end([data[, encoding]][, callback])
#
data
<string> | <Buffer> | <Uint8Array>encoding
<string>callback
<Function>- 返回:<this>
此方法向服务器发出信号,表明所有响应标头和正文均已发送;服务器应将此消息视为已完成。必须对每个响应调用该方法 response.end()
。
如果指定了 data
,则相当于调用 response.write(data, encoding)
,后跟 response.end(callback)
。
如果指定了 callback
,则在响应流完成后将调用它。
response.finished
#
response.writableEnded
。布尔值,指示响应是否已完成。从 false
开始。在 response.end()
执行后,该值将变为 true
。
response.getHeader(name)
#
读出已排队但未发送给客户端的标头。名称不区分大小写。
const contentType = response.getHeader('content-type');
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
#
如果已发送标头,则为 true,否则为 false(只读)。
response.removeHeader(name)
#
name
<string>
删除已排队以进行隐式发送的标头。
response.removeHeader('Content-Encoding');
response.req
#
对原始 HTTP2 request
对象的引用。
response.sendDate
#
如果标头中尚未存在 Date 标头,则当该值为 true 时,该标头将自动生成并发送在响应中。默认为 true。
仅应在测试时禁用此功能;HTTP 要求响应中存在 Date 标头。
response.setHeader(name, value)
#
name
<string>value
<string> | <string[]>
设置隐式标头的单个标头值。如果此标头已存在于待发送的标头中,则其值将被替换。在此处使用字符串数组以发送具有相同名称的多个标头。
response.setHeader('Content-Type', 'text/html; charset=utf-8');
或
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
尝试设置包含无效字符的头字段名或值将导致抛出TypeError
。
当标头已使用 response.setHeader()
设置时,它们将与传递给 response.writeHead()
的任何标头合并,而传递给 response.writeHead()
的标头具有优先权。
// Returns content-type = text/plain
const server = http2.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('ok');
});
response.setTimeout(msecs[, callback])
#
msecs
<number>callback
<Function>- 返回:<http2.Http2ServerResponse>
将Http2Stream
的超时值设置为msecs
。如果提供了回调,则将其添加为响应对象上'timeout'
事件的侦听器。
如果未向请求、响应或服务器添加'timeout'
侦听器,则Http2Stream
将在超时时销毁。如果已将处理程序分配给请求、响应或服务器的'timeout'
事件,则必须显式处理超时的套接字。
response.socket
#
返回一个Proxy
对象,该对象充当net.Socket
(或tls.TLSSocket
),但会根据 HTTP/2 逻辑应用 getter、setter 和方法。
destroyed
、readable
和 writable
属性将从 response.stream
中检索并设置在 response.stream
上。
destroy
、emit
、end
、on
和 once
方法将在 response.stream
上调用。
setTimeout
方法将在 response.stream.session
上调用。
pause
、read
、resume
和write
将抛出一个错误,错误代码为ERR_HTTP2_NO_SOCKET_MANIPULATION
。有关更多信息,请参阅Http2Session
和套接字。
所有其他交互都将直接路由到套接字。
const http2 = require('node:http2');
const server = http2.createServer((req, res) => {
const ip = req.socket.remoteAddress;
const port = req.socket.remotePort;
res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);
response.statusCode
#
在使用隐式标头(不显式调用 response.writeHead()
)时,此属性控制在标头刷新时将发送给客户端的状态代码。
response.statusCode = 404;
在响应标头发送给客户端后,此属性指示已发送的状态代码。
response.statusMessage
#
HTTP/2(RFC 7540 8.1.2.4)不支持状态消息。它返回一个空字符串。
response.stream
#
支持响应的Http2Stream
对象。
response.writableEnded
#
在调用response.end()
后为true
。此属性不表示数据是否已刷新,为此请改用writable.writableFinished
。
response.write(chunk[, encoding][, callback])
#
chunk
<string> | <Buffer> | <Uint8Array>encoding
<string>callback
<Function>- 返回:<boolean>
如果调用此方法且未调用response.writeHead()
,它将切换到隐式标头模式并刷新隐式标头。
这会发送响应正文的一部分。此方法可以多次调用以提供正文的连续部分。
在 node:http
模块中,当请求为 HEAD 请求时,会省略响应正文。类似地,204
和 304
响应不得包含消息正文。
chunk
可以是字符串或缓冲区。如果 chunk
是字符串,第二个参数指定如何将其编码为字节流。默认情况下,encoding
为 'utf8'
。当刷新此数据块时,将调用 callback
。
这是原始 HTTP 正文,与可能使用的更高级别多部分正文编码无关。
第一次调用response.write()
时,它会将缓冲的标头信息和正文的第一部分发送到客户端。第二次调用response.write()
时,Node.js 假设数据将被流式传输,并单独发送新数据。也就是说,响应被缓冲到正文的第一部分。
如果整个数据已成功刷新到内核缓冲区,则返回 true
。如果全部或部分数据在用户内存中排队,则返回 false
。当缓冲区再次可用时,将发出 'drain'
。
response.writeContinue()
#
向客户端发送状态 100 Continue
,指示应发送请求正文。请参阅 Http2Server
和 Http2SecureServer
上的 'checkContinue'
事件。
response.writeEarlyHints(hints)
#
hints
<Object>
向客户端发送状态 103 Early Hints
,并带有 Link 标头,指示用户代理可以预加载/预连接链接的资源。hints
是一个对象,其中包含要随早期提示消息一起发送的标头值。
示例
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,
});
response.writeHead(statusCode[, statusMessage][, headers])
#
statusCode
<number>statusMessage
<string>headers
<Object> | <Array>- 返回:<http2.Http2ServerResponse>
向请求发送响应标头。状态代码是 3 位数的 HTTP 状态代码,例如 404
。最后一个参数 headers
是响应标头。
返回对 Http2ServerResponse
的引用,以便可以链接调用。
为了与 HTTP/1 兼容,可以将可读的 statusMessage
作为第二个参数传递。但是,由于 statusMessage
在 HTTP/2 中没有意义,因此该参数不会产生任何效果,并且会发出进程警告。
const body = 'hello world';
response.writeHead(200, {
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'text/plain; charset=utf-8',
});
Content-Length
以字节为单位给出,而不是字符。Buffer.byteLength()
API 可用于确定给定编码中的字节数。在出站消息中,Node.js 不会检查 Content-Length 和正在传输的主体长度是否相等。但是,在接收消息时,当 Content-Length
与实际有效负载大小不匹配时,Node.js 会自动拒绝消息。
在调用 response.end()
之前,可以在消息上最多调用此方法一次。
如果在调用此方法之前调用了 response.write()
或 response.end()
,则将计算隐式/可变标头并调用此函数。
当标头已使用 response.setHeader()
设置时,它们将与传递给 response.writeHead()
的任何标头合并,而传递给 response.writeHead()
的标头具有优先权。
// Returns content-type = text/plain
const server = http2.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('ok');
});
尝试设置包含无效字符的头字段名或值将导致抛出TypeError
。
收集 HTTP/2 性能指标#
可以使用Performance Observer API 为每个Http2Session
和Http2Stream
实例收集基本性能指标。
const { PerformanceObserver } = require('node:perf_hooks');
const obs = new PerformanceObserver((items) => {
const entry = items.getEntries()[0];
console.log(entry.entryType); // prints 'http2'
if (entry.name === 'Http2Session') {
// Entry contains statistics about the Http2Session
} else if (entry.name === 'Http2Stream') {
// Entry contains statistics about the Http2Stream
}
});
obs.observe({ entryTypes: ['http2'] });
PerformanceEntry
的entryType
属性将等于'http2'
。
PerformanceEntry
的name
属性将等于'Http2Stream'
或'Http2Session'
。
如果name
等于Http2Stream
,则PerformanceEntry
将包含以下附加属性
bytesRead
<number>为此Http2Stream
接收的DATA
帧字节数。bytesWritten
<number>为此Http2Stream
发送的DATA
帧字节数。id
<number>关联的Http2Stream
的标识符timeToFirstByte
<number>PerformanceEntry
startTime
和接收第一个DATA
帧之间经过的毫秒数。timeToFirstByteSent
<number>PerformanceEntry
startTime
和发送第一个DATA
帧之间经过的毫秒数。timeToFirstHeader
<number>PerformanceEntry
startTime
和接收第一个标头之间经过的毫秒数。
如果name
等于Http2Session
,则PerformanceEntry
将包含以下附加属性
bytesRead
<number>为此Http2Session
接收的字节数。bytesWritten
<number>为此Http2Session
发送的字节数。framesReceived
<number>Http2Session
接收的 HTTP/2 帧数。framesSent
<number>Http2Session
发送的 HTTP/2 帧数。maxConcurrentStreams
<number> 在Http2Session
的生命周期内同时打开的最大流数。pingRTT
<number> 自发送PING
帧和接收其确认以来经过的毫秒数。仅当在Http2Session
上发送了PING
帧时才存在。streamAverageDuration
<number> 所有Http2Stream
实例的平均持续时间(以毫秒为单位)。streamCount
<number> 由Http2Session
处理的Http2Stream
实例数。type
<string>'server'
或'client'
,用于标识Http2Session
的类型。
关于 :authority
和 host
的说明#
HTTP/2 要求请求具有 :authority
伪首部或 host
首部。在直接构建 HTTP/2 请求时优先使用 :authority
,在从 HTTP/1 转换时(例如,在代理中)优先使用 host
。
如果不存在 :authority
,兼容性 API 将回退到 host
。有关更多信息,请参阅 request.authority
。但是,如果你不使用兼容性 API(或直接使用 req.headers
),则需要自己实现任何回退行为。