- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲(Buffer)
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入 Node环境
- 子进程(Child processes)
- 集群(Cluster)
- 命令行选项
- 控制台(Console)
- 核心包(Corepack)
- 加密(Crypto)
- 调试器(Debugger)
- 已弃用的 API
- 诊断通道(Diagnostics Channel)
- 域名系统(DNS)
- 域(Domain)
- 错误(Errors)
- 事件(Events)
- 文件系统(File system)
- 全局变量(Globals)
- HTTP
- HTTP/2
- HTTPS
- 检查器(Inspector)
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:module
API - 模块:packages 模块
- 网络(Net)
- 系统(OS)
- 路径(Path)
- 性能挂钩(Performance hooks)
- 性能挂钩(Permissions)
- 进程(Process)
- Punycode 国际化域名编码
- 查询字符串(Query strings)
- 命令行库(Readline)
- REPL 交互式编程环境
- 诊断报告
- 单个可执行应用程序
- Stream 流
- 字符串解码器
- 单元测试
- 定时器(Timers)
- 传输层安全/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用程序
- V8
- 虚拟机
- WebAssembly
- Web加密 API(Web Crypto API)
- 网络流 API(Web Streams API)
- 工作线程(Worker threads)
- zlib
Node.js v18.18.2 文档
- Node.js v18.18.2
-
►
目录
- HTTP/2
- Determining if crypto support is unavailable
- Core API
- Server-side example
- Client-side example
- Class:
Http2Session
Http2Session
and sockets- Event:
'close'
- Event:
'connect'
- Event:
'error'
- Event:
'frameError'
- Event:
'goaway'
- Event:
'localSettings'
- Event:
'ping'
- Event:
'remoteSettings'
- Event:
'stream'
- Event:
'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()
- Class:
ServerHttp2Session
- Class:
ClientHttp2Session
- Class:
Http2Stream
Http2Stream
Lifecycle- Event:
'aborted'
- Event:
'close'
- Event:
'error'
- Event:
'frameError'
- Event:
'ready'
- Event:
'timeout'
- Event:
'trailers'
- Event:
'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)
- Class:
ClientHttp2Stream
- Class:
ServerHttp2Stream
- Class:
Http2Server
- Class:
Http2SecureServer
http2.createServer([options][, onRequestHandler])
http2.createSecureServer(options[, onRequestHandler])
http2.connect(authority[, options][, listener])
http2.constants
http2.getDefaultSettings()
http2.getPackedSettings([settings])
http2.getUnpackedSettings(buf)
http2.sensitiveHeaders
- Headers object
- Settings object
- Error handling
- Invalid character handling in header names and values
- Push streams on the client
- Supporting the
CONNECT
method - The extended
CONNECT
protocol
- Compatibility API
- ALPN negotiation
- Class:
http2.Http2ServerRequest
- Event:
'aborted'
- Event:
'close'
request.aborted
request.authority
request.complete
request.connection
request.destroy([error])
request.headers
request.httpVersion
request.method
request.rawHeaders
request.rawTrailers
request.scheme
request.setTimeout(msecs, callback)
request.socket
request.stream
request.trailers
request.url
- Event:
- Class:
http2.Http2ServerResponse
- Event:
'close'
- Event:
'finish'
response.addTrailers(headers)
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])
- Event:
- Collecting HTTP/2 performance metrics
- Note on
:authority
andhost
- HTTP/2
-
►
索引
- Assertion testing
- Asynchronous context tracking
- Async hooks
- Buffer
- C++ addons
- C/C++ addons with Node-API
- C++ embedder API
- Child processes
- Cluster
- Command-line options
- Console
- Corepack
- Crypto
- Debugger
- Deprecated APIs
- Diagnostics Channel
- DNS
- Domain
- Errors
- Events
- File system
- Globals
- HTTP
- HTTP/2
- HTTPS
- Inspector
- Internationalization
- Modules: CommonJS modules
- Modules: ECMAScript modules
- Modules:
node:module
API - Modules: Packages
- Net
- 系统(OS)
- 路径(Path)
- Performance hooks
- Permissions
- 进程(Process)
- Punycode
- Query strings
- 命令行库(Readline)
- REPL 交互式编程环境
- Report
- Single executable applications
- Stream
- String decoder
- Test runner
- Timers
- TLS/SSL
- Trace events
- TTY
- UDP/datagram
- URL
- Utilities
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- Worker threads
- Zlib
- ► 其他版本
- ► 选项
目录
- 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([settings])
http2.getUnpackedSettings(buf)
http2.sensitiveHeaders
- 标头对象
- 设置对象
- 错误处理
- 标头名称和值中的无效字符处理
- 客户端推流
- 支持
CONNECT
方法 - 扩展的
CONNECT
协议
- 兼容性API
- ALPN协商
- 类:
http2.Http2ServerRequest
- 事件:
'aborted'
- 事件:
'close'
request.aborted
request.authority
request.complete
request.connection
request.destroy([error])
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.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#
源代码: 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
Core API 在客户端和服务器之间比http
API更加对称
。例如,大多数事件(如'error'
、'connect'
和
'stream'
)可以由客户端代码或服务器端代码发出。
服务器端示例#
下面说明了使用 Core 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://localhost: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 连接时,服务器端
Http2Session
实例由Http2Server
实例创建。客户端Http2Session
实例是使用http2.connect()
方法创建的。
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
<错误>
当处理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');
});
在服务器端,用户代码通常不会直接侦听此事件,而是为net.Server
或tls.Server
发出的 'stream'
事件
注册处理程序分别由http2.createServer()
和
http2.createSecureServer()
返回的实例,如下例所示:
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
,或将返回连接的TLSSocket
自己的alpnProtocol
属性的值
。
http2session.close([callback])
#
callback
<函数>
优雅地关闭Http2Session
,允许任何现有流自行完成并防止创建新的Http2Stream
实例。关闭后,如果没有打开的Http2Stream
实例,则可能会调用http2session.destroy()
。
如果指定,则callback
函数将注册为
'close'
事件的处理程序。
http2session.closed
#
如果此Http2Session
实例已关闭,则为 true
,否则为
false
。
http2session.connecting
#
如果此Http2Session
实例仍在连接,则为true
,在发出connect
事件和/或调用http2.connect
回调。
http2session.destroy([error][, code])
#
error
<Error>如果Http2Session
由于错误而被销毁,则为Error
对象。code
<number>在最后的GOAWAY
帧中发送的 HTTP/2 错误代码。如果未指定,且error
未定义,则默认为INTERNAL_ERROR
,否则默认为NO_ERROR
。
立即终止Http2Session
和关联的net.Socket
或
tls.TLSSocket
。
一旦被销毁,Http2Session
将发出'close'
事件。如果error
未定义,则'error'
事件将在'close'
事件之前立即发出
。
如果还有任何与Http2Session
关联的
剩余打开的Http2Streams
,它们也将被销毁。
http2session.destroyed
#
如果此Http2Session
实例已被销毁且不能再使用,则为 true
,否则为false
。
http2session.encrypted
#
如果Http2Session
会话套接字尚未连接,则值为undefined
;如果Http2Session
已与TLSSocket
}连接,则值为true
和false
如果Http2Session
连接到任何其他类型的套接字或流。
http2session.goaway([code[, lastStreamID[, opaqueData]]])
#
code
<number> HTTP/2 错误代码lastStreamID
<number>最后处理的Http2Stream
的数字 IDopaqueData
<缓冲区> | <类型化数组> | <DataView>一个TypedArray
或DataView
实例,包含要在GOAWAY
框架内携带的附加数据。
将GOAWAY
帧传输到连接的对等点,而不关闭
Http2Session
。
http2session.localSettings
#
一个无原型对象,描述此
Http2Session
的当前本地设置。本地设置是此 Http2Session
实例的本地设置。
http2session.originSet
#
如果Http2Session
连接到TLSSocket
,则originSet
属性将返回Array
的来源,其中Http2Session
可以被认为是权威的。
originSet
属性仅在使用安全 TLS 连接时可用。
http2session.pendingSettingsAck
#
指示Http2Session
当前是否正在等待已发送的SETTINGS
帧的确认。调用http2session.settings()
方法后将
是true
。一旦所有发送的SETTINGS
帧
均得到确认,将为false
。
http2session.ping([payload, ]callback)
#
payload
<缓冲区> | <类型化数组> | <DataView>可选的 ping 负载。callback
<函数>- 返回:<布尔值>
向连接的 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
<数字>
设置本地端点的窗口大小。windowSize
是要设置的总窗口大小,而不是增量。
const http2 = require('node:http2');
const server = http2.createServer();
const expectedWindowSize = 2 ** 20;
server.on('connect', (session) => {
// Set local window size to be 2 ** 20
session.setLocalWindowSize(expectedWindowSize);
});
http2session.setTimeout(msecs, callback)
#
用于设置当msecs
毫秒后Http2Session
上没有事件时调用的回调函数。给定的callback
已注册为'timeout'
事件的侦听器。
http2session.socket
#
返回一个Proxy
对象,该对象充当net.Socket
(或tls.TLSSocket
),但将可用方法限制为可以安全地与 HTTP/2 一起使用的方法。
destroy
、emit
、end
、pause
、read
、resume
和write
将引发错误,代码为ERR_HTTP2_NO_SOCKET_MANIPULATION
。有关详细信息,请参阅
Http2Session
和套接字。
将在此Http2Session
上调用setTimeout
方法。
所有其他交互将直接路由到套接字。
http2session.state
#
提供有关Http2Session
当前状态的各种信息
。
- <对象>
effectiveLocalWindowSize
<number>Http2Session
的当前本地(接收)流量控制窗口大小。effectiveRecvDataLength
<number>自上次流量控制WINDOW_UPDATE
以来已接收的当前字节数。nextStreamID
<number>此Http2Session
下次创建新的Http2Stream
时要使用的数字标识符。localWindowSize
<number>远程对等方在不接收WINDOW_UPDATE
的情况下可以发送的字节数。lastProcStreamID
<number>最近收到的HEADERS
或DATA
帧 的Http2Stream
的数字 ID 。remoteWindowSize
<number>此Http2Session
在没有接收到WINDOW_UPDATE
的 情况下可以发送的字节数。outboundQueueSize
<number>此Http2Session
当前出站队列中的帧数。deflateDynamicTableSize
<number>出站标头压缩状态表的当前大小(以字节为单位)。inflateDynamicTableSize
<number>入站标头压缩状态表的当前大小(以字节为单位)。
描述此Http2Session
当前状态的对象。
http2session.settings([settings][, callback])
#
settings
<HTTP/2 设置对象>callback
<Function>会话连接后或会话已连接时立即调用的回调。err
<错误> | <空>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
将等于 http2.constants.NGHTTP2_SESSION_CLIENT
。
http2session.unref()
#
在此Http2Session
实例的底层net.Socket
上调用unref()
。
类:ServerHttp2Session
#
serverhttp2session.altsvc(alt, originOrStream)
#
alt
<string> RFC 7838定义的替代服务配置的描述。originOrStream
<数字> | <字符串> | <网址> | <Object>指定来源的 URL 字符串(或具有origin
属性的Object
)或事件Http2Stream
的数字标识符,如http2stream.id
属性。
向连接的客户端提交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
和原始字符串必须仅包含 ASCII 字节,并严格解释为 ASCII 字节序列。
可以传递特殊值'clear'
以清除之前为给定域设置的任何替代服务。
当为originOrStream
参数传递字符串时,它将被解析为 URL 并导出源。例如,HTTP URL 'https://example.org/foo/bar'
的来源是 ASCII 字符串
'https://example.org'
。如果给定的字符串无法解析为 URL 或者无法导出有效的源,则会抛出错误。
URL
对象或任何具有origin
属性的对象可以作为
originOrStream
传递,在这种情况下, origin
的值将使用财产。origin
属性的值必须是正确序列化的 ASCII 源。
指定替代服务#
alt
参数的格式由RFC 7838严格定义为 ASCII 字符串,其中包含与特定主机和端口关联的以逗号分隔的“替代”协议列表。
例如,值'h2="example.org:81"'
表示 HTTP/2 协议在 TCP/IP 端口 81 上的主机'example.org'
上可用。主机和端口必须包含在引号 ( "
) 个字符。
可以指定多个替代方案,例如:'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
<字符串[]>
每当客户端收到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
<boolean>true
如果Http2Stream
可 写端最初应关闭,例如发送不应期望的GET
请求时有效负载主体。exclusive
<boolean>当true
和parent
标识父流时,创建的流将成为父流的唯一直接依赖项,所有其他现有依赖项也将成为父流的唯一直接依赖项新创建的流的依赖项。 默认值:false
。parent
<number>指定新创建的流所依赖的流的数字标识符。weight
<number>指定流相对于具有相同parent
的其他流的相对依赖性。该值为1
和256
(含)之间的数字。waitForTrailers
<boolean>当true
时,Http2Stream
将在最后一个DATA
帧结束后发出'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://localhost: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
时,当传输最后一个DATA
帧时, Http2Stream
不会自动关闭。用户代码必须调用
http2stream.sendTrailers()
或http2stream.close()
来关闭
Http2Stream
。
当options.signal
设置为AbortSignal
,然后调用相应的AbortController
上的 abort
时,请求将发出'error'
事件,出现AbortError
错误。
:method
和:path
伪标头未在headers
中指定,它们分别默认为:
:method
='GET'
:path
=/
类:Http2Stream
#
Http2Stream
类的每个实例都表示通过Http2Session
实例的双向 HTTP/2 通信流。任何单个Http2Session
在其生命周期内
最多可以有 2 31 -1 Http2Stream
实例。
用户代码不会直接构造Http2Stream
实例。相反,它们是通过Http2Session
实例创建、管理并提供给用户代码的
。在服务器上,创建Http2Stream
实例是为了响应传入的 HTTP 请求(并通过'stream'
事件移交给用户代码),或者是为了响应对http2stream.pushStream()
方法。在客户端上,当调用 http2session.request()
方法或响应传入的
'push'
事件时,会创建并返回 Http2Stream
实例
。
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()
方法。
在客户端,当调用http2session.request()
方法时,会创建 ClientHttp2Stream
的实例。
在客户端上,如果父 Http2Session
尚未完全建立,则http2session.request()
返回的 Http2Stream
实例
可能无法立即可供使用。在这种情况下,对Http2Stream
调用的操作
将被缓冲,直到发出'ready'
事件。用户代码应该很少(如果有的话)需要直接处理'ready'
事件。Http2Stream
的就绪状态
可以通过检查http2stream.id
的值来确定。如果值为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
<错误>
当处理Http2Stream
期间发生错误时,会发出'error'
事件。
事件:'frameError'
#
当尝试发送帧时发生错误时,会发出'frameError'
事件。调用时,处理函数将接收一个标识帧类型的整数参数和一个标识错误代码的整数参数。Http2Stream
实例将在'frameError'
事件发出后立即销毁
。
事件:'ready'
#
当 Http2Stream
打开、分配了 id
并可以使用时,会发出 'ready'
事件。听者不需要任何争论。
事件:'timeout'
#
在使用http2stream.setTimeout()
设置的毫秒数内
没有收到此
Http2Stream
的任何事件后,将发出'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
#
如果在收到的请求或响应标头帧中设置了 END_STREAM
标志,则设置为 true
,表示不应接收其他数据并且 Http2Stream
的可读侧将被关闭。
http2stream.id
#
此Http2Stream
实例的数字流标识符。
如果尚未分配流标识符,则设置为undefined
。
http2stream.pending
#
如果尚未为Http2Stream
实例分配数字流标识符,则设置为 true
。
http2stream.priority(options)
#
options
<对象>
更新此Http2Stream
实例的优先级。
http2stream.rstCode
#
设置为在从连接的对等方接收到RST_STREAM
帧并调用 http2stream.close()
后 Http2Stream
被销毁时报告的RST_STREAM
错误代码,或http2stream.destroy()
。如果
Http2Stream
尚未关闭,则为 undefined
。
http2stream.sentHeaders
#
包含为此Http2Stream
发送的出站标头的对象。
http2stream.sentInfoHeaders
#
包含为此Http2Stream
发送的出站信息(附加)标头的对象数组。
http2stream.sentTrailers
#
包含为此HttpStream
发送的出站预告片的对象。
http2stream.session
#
对拥有此Http2Stream
的 Http2Session
实例的引用。Http2Stream
实例被销毁后,该值将为undefined
。
http2stream.setTimeout(msecs, callback)
#
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>连接的对等方可以为此Http2Stream
发送的字节数,而不会收到WINDOW_UPDATE
。state
<number>指示由nghttp2
确定的Http2Stream
的低级当前状态的标志 。localClose
<number>1
如果此Http2Stream
已在本地关闭。remoteClose
<number>1
如果此Http2Stream
已远程关闭。sumDependencyWeight
<number>使用PRIORITY
框架指定的 依赖于此Http2Stream
的所有Http2Stream
实例的总权重。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
<数字>
当接收到流的附加标头块时,例如当接收到1xx
信息标头块时,会发出 'headers'
事件。侦听器回调将传递HTTP/2 标头对象和与标头关联的标志。
stream.on('headers', (headers, flags) => {
console.log(headers);
});
事件:'push'
#
headers
<HTTP/2 标头对象>flags
<数字>
当收到服务器推送流的响应标头时,会发出'push'
事件。侦听器回调将传递HTTP/2 标头对象和与标头关联的标志。
stream.on('push', (headers, flags) => {
console.log(headers);
});
事件:'response'
#
headers
<HTTP/2 标头对象>flags
<数字>
当从连接的 HTTP/2 服务器收到此流的响应HEADERS
帧时,会发出 'response'
事件。使用两个参数调用侦听器:包含接收到的
HTTP/2 Headers Object 的Object
以及与标头关联的标志。
const http2 = require('node:http2');
const client = http2.connect('https://localhost');
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
<错误>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
时,当传输最后一个DATA
帧时, Http2Stream
不会自动关闭。用户代码必须调用
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
<数字> | <FileHandle>可读文件描述符。headers
<HTTP/2 标头对象>options
<对象>
启动一个响应,其数据是从给定的文件描述符中读取的。不对给定的文件描述符执行任何验证。如果尝试使用文件描述符读取数据时发生错误,则将使用标准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 Range 请求。
当流关闭时,文件描述符或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
<字符串> | <缓冲区> | <网址>headers
<HTTP/2 标头对象>options
<对象>statCheck
<函数>onError
<Function>发送前发生错误时调用的回调函数。waitForTrailers
<boolean>当true
时,Http2Stream
将在最后一个DATA
帧结束后发出'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 Range 请求。
options.onError
函数还可用于处理在启动文件传送之前可能发生的所有错误。默认行为是销毁流。
当设置了options.waitForTrailers
选项时,在排队要发送的最后一块有效负载数据后,将立即发出 'wantTrailers'
事件。然后可以使用http2stream.sendTrailers()
方法将尾随标头字段发送到对等方。
当设置了options.waitForTrailers
时,当传输最后一个DATA
帧时, Http2Stream
不会自动关闭。用户代码必须调用
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
<流.Duplex>
当建立新的 TCP 流时会发出此事件。socket
通常是net.Socket
类型的对象。通常用户不想访问此事件。
用户还可以显式发出此事件,以将连接注入 HTTP 服务器。在这种情况下,任何Duplex
流都可以传递。
事件:'request'
#
request
<http2.Http2ServerRequest>response
<http2.Http2ServerResponse>
每次有请求时发出。每个会话可能有多个请求。请参阅兼容性 API。
事件:'session'
#
session
<ServerHttp2Session>
当Http2Server
创建
新的Http2Session
时,会发出'session'
事件。
事件:'sessionError'
#
error
<错误>session
<ServerHttp2Session>
当与Http2Server
关联的 Http2Session
对象发出'error'
事件时,会发出'sessionError'
事件。
事件:'stream'
#
stream
<Http2Stream>对流的引用headers
<HTTP/2 Headers Object>描述标头的对象flags
<number>关联的数字标志rawHeaders
<Array>包含原始标头名称及其各自值的数组。
当与服务器关联的Http2Session
发出'stream'
事件时,会发出 '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
<函数>
停止服务器建立新会话。由于 HTTP/2 会话的持久性,这不会阻止创建新的请求流。要正常关闭服务器,请在所有事件会话上调用http2session.close()
。
如果提供了callback
,则在关闭所有事件会话之前不会调用它,尽管服务器已停止允许新会话。请参阅
net.Server.close()
了解更多详情。
server.setTimeout([msecs][, callback])
#
msecs
<number> 默认值: 0(无超时)callback
<函数>- 返回:<Http2Server>
用于设置http2服务器请求的超时值,并设置在msecs
毫秒后Http2Server
上没有事件时调用的回调函数。
给定的回调被注册为'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
<流.Duplex>
在 TLS 握手开始之前建立新的 TCP 流时会发出此事件。socket
通常是net.Socket
类型的对象。通常用户不想访问此事件。
用户还可以显式发出此事件,以将连接注入 HTTP 服务器。在这种情况下,任何Duplex
流都可以传递。
事件:'request'
#
request
<http2.Http2ServerRequest>response
<http2.Http2ServerResponse>
每次有请求时发出。每个会话可能有多个请求。请参阅兼容性 API。
事件:'session'
#
session
<ServerHttp2Session>
当Http2SecureServer
创建
新的Http2Session
时,会发出'session'
事件。
事件:'sessionError'
#
error
<错误>session
<ServerHttp2Session>
当与Http2SecureServer
关联的Http2Session
对象发出'error'
事件时,会发出'sessionError'
事件。
事件:'stream'
#
stream
<Http2Stream>对流的引用headers
<HTTP/2 Headers Object>描述标头的对象flags
<number>关联的数字标志rawHeaders
<Array>包含原始标头名称及其各自值的数组。
当与服务器关联的Http2Session
发出'stream'
事件时,会发出 '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
<流.Duplex>
当连接客户端无法协商允许的协议(即 HTTP/2 或 HTTP/1.1)时,会发出'unknownProtocol'
事件。事件处理程序接收套接字进行处理。如果没有为此事件注册侦听器,则连接将终止。可以使用传递给http2.createSecureServer()
的'unknownProtocolTimeout'
选项来指定超时
。请参阅兼容性 API。
server.close([callback])
#
callback
<函数>
停止服务器建立新会话。由于 HTTP/2 会话的持久性,这不会阻止创建新的请求流。要正常关闭服务器,请在所有事件会话上调用http2session.close()
。
如果提供了callback
,则在关闭所有事件会话之前不会调用它,尽管服务器已停止允许新会话。请参阅
tls.Server.close()
了解更多详情。
server.setTimeout([msecs][, callback])
#
msecs
<数字> 默认值:120000
(2 分钟)callback
<函数>- 返回:<Http2SecureServer>
用于设置http2安全服务器请求的超时值,并设置在msecs
毫秒后Http2SecureServer
上没有事件时调用的回调函数。
给定的回调被注册为'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
<integer>设置会话关闭之前允许的最大无效帧数。 默认值:1000
。maxSessionRejectedStreams
<integer>设置在会话关闭之前可容忍的创建流时被拒绝的最大数量。每次拒绝都与一个NGHTTP2_ENHANCE_YOUR_CALM
错误相关联 ,该错误应该告诉对等方不要再打开任何流,因此继续打开流被视为对等方行为不当的标志。 默认值:100
。settings
<HTTP/2 设置对象>连接时发送到远程对等点的初始设置。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
<number>指定发出'unknownProtocol'
时服务器应等待的超时(以毫秒为单位) 。如果此时套接字尚未销毁,服务器将销毁它。 默认值:10000
。- ...:可以提供任何
net.createServer()
选项。
onRequestHandler
<函数>请参阅兼容性 API- 返回:<Http2Server>
返回一个创建和管理Http2Session
实例的net.Server
实例。
由于没有已知的浏览器支持
未加密的 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
<integer>设置会话关闭之前允许的最大无效帧数。 默认值:1000
。maxSessionRejectedStreams
<integer>设置在会话关闭之前允许创建的流被拒绝的最大数量。每次拒绝都与一个NGHTTP2_ENHANCE_YOUR_CALM
错误相关联 ,该错误应该告诉对等方不要再打开任何流,因此继续打开流被视为对等方行为不当的标志。 默认值:100
。settings
<HTTP/2 设置对象>连接时发送到远程对等点的初始设置。- ...:可以提供任何
tls.createServer()
选项。对于服务器,通常需要身份选项(pfx
或key
/cert
)。 origins
<string[]> 创建新服务器Http2Session
后立即在ORIGIN
帧内发送的原始字符串数组。unknownProtocolTimeout
<number>指定发出'unknownProtocol'
事件时服务器应等待的超时(以毫秒为单位) 。如果此时套接字尚未销毁,服务器将销毁它。 默认值:10000
。
onRequestHandler
<函数>请参阅兼容性 API- 返回:<Http2SecureServer>
返回一个创建和管理Http2Session
实例的tls.Server
实例。
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
<字符串> | <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。最大允许值为 2 32 -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 设置对象>连接时发送到远程对等点的初始设置。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://localhost: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
实例,其中包含 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
<缓冲区> | <TypedArray>打包的设置。- 返回:<HTTP/2 设置对象>
返回一个HTTP/2 设置对象,其中包含由http2.getPackedSettings()
生成的给定Buffer
的反序列化设置。
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。最大允许值为 2 32 -1。默认值:4096
。enablePush
<boolean>指定true
实例上是否允许 HTTP/2 推送流。默认值:true
。initialWindowSize
<number>指定发送方用于流级流量控制的初始窗口大小(以字节为单位)。最小允许值为 0。最大允许值为 2 32 -1。默认值:65535
。maxFrameSize
<number>指定最大帧负载的大小(以字节为单位)。允许的最小值是 16,384。最大允许值为 2 24 -1。默认值:16384
。maxConcurrentStreams
<number>指定Http2Session
上允许的最大并发流数。没有默认值,这意味着至少在理论上,可以在Http2Session
中的任何给定时间同时打开2 32 -1 个流。最小值为 0。允许的最大值为 2 32 -1。默认值:4294967295
。maxHeaderListSize
<number>指定将接受的标头列表的最大大小(未压缩八位字节)。最小允许值为 0。最大允许值为 2 32 -1。默认值:65535
。maxHeaderSize
<number>maxHeaderListSize
的别名。enableConnectProtocol
<boolean>指定true
是否启用RFC 8441定义的“扩展连接协议” 。此设置仅在由服务器发送时才有意义。一旦为给定的Http2Session
启用了enableConnectProtocol
设置,就无法将其禁用。 默认值:false
。
设置对象上的所有其他属性都将被忽略。
错误处理#
使用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('http://localhost');
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('http://localhost: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
方法作为其他通信协议(例如作为 WebSocket)。
HTTP/2 服务器通过使用enableConnectProtocol
设置来启用扩展 CONNECT 协议:
const http2 = require('node:http2');
const settings = { enableConnectProtocol: true };
const server = http2.createServer({ settings });
一旦客户端从服务器接收到指示可以使用扩展 CONNECT 的SETTINGS
帧,它就可以发送使用
':protocol'
HTTP/2 伪协议的 CONNECT
请求-标题:
const http2 = require('node:http2');
const client = http2.connect('http://localhost: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
组成。它们的目标是 API 与 HTTP/1 兼容,但它们并没有隐藏协议之间的差异。例如,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
<错误>
在收到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
<数字>callback
<函数>- 返回:<http2.Http2ServerRequest>
将Http2Stream
的超时值设置为msecs
。如果提供了回调,则会将其添加为响应对象上的'timeout'
事件的侦听器。
如果没有向请求、响应或服务器添加'timeout'
侦听器,则Http2Stream
会在超时时被销毁。如果将处理程序分配给请求、响应或服务器的'timeout'
事件,则必须显式处理超时套接字。
request.socket
#
返回一个Proxy
对象,该对象充当net.Socket
(或tls.TLSSocket
),但应用基于 HTTP/2 逻辑的 getter、setter 和方法。
destroyed
、readable
和writable
属性将从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
#
- 扩展:<流>
该对象是由 HTTP 服务器内部创建的,而不是由用户创建的。它作为第二个参数传递给'request'
事件。
事件:'close'
#
指示底层Http2Stream
在response.end()
被调用或能够刷新之前终止
。
事件:'finish'
#
发送响应后发出。更具体地说,当响应标头和正文的最后一段已移交给 HTTP/2 多路复用以通过网络传输时,会发出此事件。这并不意味着客户已经收到任何东西。
在此事件之后,响应对象上将不再发出任何事件。
response.addTrailers(headers)
#
headers
<对象>
此方法将 HTTP 尾随标头(位于消息末尾的标头)添加到响应中。
尝试设置包含无效字符的标头字段名称或值将导致抛出TypeError
。
response.connection
#
response.socket
。请参阅response.socket
。
response.createPushResponse(headers, callback)
#
headers
<HTTP/2 Headers Object>描述标头的对象callback
<Function>在http2stream.pushStream()
完成后调用,或者在创建推送的Http2Stream
的尝试失败或被拒绝时调用,或者Http2ServerRequest
在调用http2stream.pushStream()
方法 之前关闭err
<错误>res
<http2.Http2ServerResponse>新创建的Http2ServerResponse
对象
使用给定的标头调用http2stream.pushStream()
,并将给定的Http2Stream
包装在新创建的Http2ServerResponse
上作为回调参数(如果成功)。当Http2ServerRequest
关闭时,调用回调并返回错误ERR_HTTP2_INVALID_STREAM
。
response.end([data[, encoding]][, callback])
#
此方法向服务器发出信号,表明所有响应标头和正文均已发送;该服务器应该认为该消息是完整的。每个响应都必须调用方法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()
#
- 返回:<字符串[]>
返回一个包含当前传出标头的唯一名称的数组。所有标头名称均为小写。
response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie']
response.getHeaders()
#
- 返回:<对象>
返回当前传出标头的浅表副本。由于使用浅拷贝,数组值可能会发生变化,而无需额外调用各种与标头相关的 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
<字符串>
删除已排队等待隐式发送的标头。
response.removeHeader('Content-Encoding');
response.req
#
对原始 HTTP2 request
对象的引用。
response.sendDate
#
如果为 true,则将自动生成 Date 标头并在响应中发送(如果标头中尚不存在)。默认为 true。
仅应在测试时禁用此功能;HTTP 要求响应中包含日期标头。
response.setHeader(name, value)
#
为隐式标头设置单个标头值。如果要发送的标头中已存在该标头,则其值将被替换。此处使用字符串数组来发送具有相同名称的多个标头。
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
<数字>callback
<函数>- 返回:<http2.Http2ServerResponse>
将Http2Stream
的超时值设置为msecs
。如果提供了回调,则会将其添加为响应对象上的'timeout'
事件的侦听器。
如果没有向请求、响应或服务器添加'timeout'
侦听器,则Http2Stream
会在超时时被销毁。如果将处理程序分配给请求、响应或服务器的'timeout'
事件,则必须显式处理超时套接字。
response.socket
#
返回一个Proxy
对象,该对象充当net.Socket
(或tls.TLSSocket
),但应用基于 HTTP/2 逻辑的 getter、setter 和方法。
destroyed
、readable
和writable
属性将从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])
#
如果调用此方法并且尚未调用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
<对象>
使用 Link 标头向客户端发送状态103 Early Hints
,指示用户代理可以预加载/预连接链接的资源。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
<数字>statusMessage
<字符串>headers
<对象> | <数组>- 返回:<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
),则需要自己实现任何后备行为。