Node.js v25.0.0 文件
- Node.js v25.0.0
-
目錄
- HTTP/2
- 確定加密支援是否不可用
- 核心 API
- 伺服器端示例
- 客戶端示例
- 類:
Http2SessionHttp2Session和套接字- 事件:
'close' - 事件:
'connect' - 事件:
'error' - 事件:
'frameError' - 事件:
'goaway' - 事件:
'localSettings' - 事件:
'ping' - 事件:
'remoteSettings' - 事件:
'stream' - 事件:
'timeout' http2session.alpnProtocolhttp2session.close([callback])http2session.closedhttp2session.connectinghttp2session.destroy([error][, code])http2session.destroyedhttp2session.encryptedhttp2session.goaway([code[, lastStreamID[, opaqueData]]])http2session.localSettingshttp2session.originSethttp2session.pendingSettingsAckhttp2session.ping([payload, ]callback)http2session.ref()http2session.remoteSettingshttp2session.setLocalWindowSize(windowSize)http2session.setTimeout(msecs, callback)http2session.sockethttp2session.statehttp2session.settings([settings][, callback])http2session.typehttp2session.unref()
- 類:
ServerHttp2Session - 類:
ClientHttp2Session - 類:
Http2StreamHttp2Stream的生命週期- 事件:
'aborted' - 事件:
'close' - 事件:
'error' - 事件:
'frameError' - 事件:
'ready' - 事件:
'timeout' - 事件:
'trailers' - 事件:
'wantTrailers' http2stream.abortedhttp2stream.bufferSizehttp2stream.close(code[, callback])http2stream.closedhttp2stream.destroyedhttp2stream.endAfterHeadershttp2stream.idhttp2stream.pendinghttp2stream.priority(options)http2stream.rstCodehttp2stream.sentHeadershttp2stream.sentInfoHeadershttp2stream.sentTrailershttp2stream.sessionhttp2stream.setTimeout(msecs, callback)http2stream.statehttp2stream.sendTrailers(headers)
- 類:
ClientHttp2Stream - 類:
ServerHttp2Stream - 類:
Http2Server - 類:
Http2SecureServer http2.createServer([options][, onRequestHandler])http2.createSecureServer(options[, onRequestHandler])http2.connect(authority[, options][, listener])http2.constantshttp2.getDefaultSettings()http2.getPackedSettings([settings])http2.getUnpackedSettings(buf)http2.performServerHandshake(socket[, options])http2.sensitiveHeaders- Headers 物件
- Settings 物件
- 錯誤處理
- Header 名稱和值中無效字元的處理
- 客戶端上的推送流
- 支援
CONNECT方法 - 擴充套件的
CONNECT協議
- 相容性 API
- ALPN 協商
- 類:
http2.Http2ServerRequest- 事件:
'aborted' - 事件:
'close' request.abortedrequest.authorityrequest.completerequest.connectionrequest.destroy([error])request.headersrequest.httpVersionrequest.methodrequest.rawHeadersrequest.rawTrailersrequest.schemerequest.setTimeout(msecs, callback)request.socketrequest.streamrequest.trailersrequest.url
- 事件:
- 類:
http2.Http2ServerResponse- 事件:
'close' - 事件:
'finish' response.addTrailers(headers)response.appendHeader(name, value)response.connectionresponse.createPushResponse(headers, callback)response.end([data[, encoding]][, callback])response.finishedresponse.getHeader(name)response.getHeaderNames()response.getHeaders()response.hasHeader(name)response.headersSentresponse.removeHeader(name)response.reqresponse.sendDateresponse.setHeader(name, value)response.setTimeout(msecs[, callback])response.socketresponse.statusCoderesponse.statusMessageresponse.streamresponse.writableEndedresponse.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
- 子程序
- 叢集
- 命令列選項
- 控制檯
- 加密
- 偵錯程式
- 已棄用的 API
- 診斷通道
- DNS
- 域
- 環境變數
- 錯誤
- 事件
- 檔案系統
- 全域性物件
- HTTP
- HTTP/2
- HTTPS
- 檢查器
- 國際化
- 模組:CommonJS 模組
- 模組:ECMAScript 模組
- 模組:
node:moduleAPI - 模組:包
- 模組:TypeScript
- 網路
- 作業系統
- 路徑
- 效能鉤子
- 許可權
- 程序
- Punycode
- 查詢字串
- 逐行讀取
- REPL
- 報告
- 單一可執行檔案應用
- SQLite
- 流
- 字串解碼器
- 測試執行器
- 定時器
- TLS/SSL
- 跟蹤事件
- TTY
- UDP/資料報
- URL
- 實用工具
- V8
- 虛擬機器
- 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()。
import { createSecureServer } from 'node:http2';
import { readFileSync } from 'node:fs';
const server = createSecureServer({
key: readFileSync('localhost-privkey.pem'),
cert: 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);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 客戶端:
import { connect } from 'node:http2';
import { readFileSync } from 'node:fs';
const client = connect('https://:8443', {
ca: 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();const http2 = require('node:http2');
const fs = require('node:fs');
const client = http2.connect('https://: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#
- 繼承自:<EventEmitter>
http2.Http2Session 類的例項表示 HTTP/2 客戶端和伺服器之間的活動通訊會話。使用者程式碼不應該直接構造該類的例項。
每個 Http2Session 例項的行為會根據其作為伺服器還是客戶端執行而略有不同。http2session.type 屬性可用於確定 Http2Session 的執行模式。在伺服器端,使用者程式碼很少需要直接操作 Http2Session 物件,大多數操作通常透過與 Http2Server 或 Http2Stream 物件互動來完成。
使用者程式碼不會直接建立 Http2Session 例項。伺服器端的 Http2Session 例項由 Http2Server 例項在接收到新的 HTTP/2 連線時建立。客戶端的 Http2Session 例項則透過 http2.connect() 方法建立。
Http2Session 和套接字#
每個 Http2Session 例項在建立時都與一個 net.Socket 或 tls.TLSSocket 相關聯。當 Socket 或 Http2Session 被銷燬時,兩者都會被銷燬。
由於 HTTP/2 協議有特定的序列化和處理要求,不建議使用者程式碼從繫結到 Http2Session 的 Socket 例項中讀取資料或向其寫入資料。這樣做可能會使 HTTP/2 會話進入不確定狀態,導致會話和套接字變得無法使用。
一旦 Socket 被繫結到 Http2Session,使用者程式碼應完全依賴於 Http2Session 的 API。
事件:'close'#
'close' 事件在 Http2Session 被銷燬後觸發。其監聽器不接收任何引數。
事件:'connect'#
session<Http2Session>socket<net.Socket>
'connect' 事件在 Http2Session 成功連線到遠端對等端並且可以開始通訊時觸發。
使用者程式碼通常不會直接監聽此事件。
事件:'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 Object> 收到的SETTINGS幀的副本。
'localSettings' 事件在收到確認 SETTINGS 幀時觸發。
當使用 http2session.settings() 提交新設定時,修改後的設定直到 'localSettings' 事件觸發後才會生效。
session.settings({ enablePush: false });
session.on('localSettings', (settings) => {
/* Use the new settings */
});
事件:'remoteSettings'#
settings<HTTP/2 Settings Object> 收到的SETTINGS幀的副本。
'remoteSettings' 事件在從連線的對等端接收到新的 SETTINGS 幀時觸發。
session.on('remoteSettings', (settings) => {
/* Use the new settings */
});
事件:'stream'#
stream<Http2Stream> 對該流的引用headers<HTTP/2 Headers Object> 描述 Headers 的物件flags<number> 相關的數字標誌rawHeaders<HTTP/2 Raw Headers> 包含原始 Headers 的陣列
'stream' 事件在建立新的 Http2Stream 時觸發。
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' 事件註冊一個處理器,如下例所示:
import { createServer } from 'node:http2';
// Create an unencrypted HTTP/2 server
const server = 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);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 流和網路套接字不是一對一對應的關係,但網路錯誤會銷燬每個單獨的流,並且必須在流級別上處理,如上所示。
事件:'timeout'#
在使用 http2session.setTimeout() 方法為此 Http2Session 設定超時期限後,如果 Http2Session 在配置的毫秒數內沒有任何活動,則會觸發 'timeout' 事件。其監聽器不接收任何引數。
session.setTimeout(2000);
session.on('timeout', () => { /* .. */ });
http2session.alpnProtocol#
- 型別:<string> | <undefined>
如果 Http2Session 尚未連線到套接字,則該值為 undefined;如果 Http2Session 未連線到 TLSSocket,則為 h2c;否則將返回所連線的 TLSSocket 自身的 alpnProtocol 屬性值。
http2session.close([callback])#
callback<Function>
平滑地關閉 Http2Session,允許任何現有流自行完成,並阻止建立新的 Http2Stream 例項。一旦關閉,如果沒有開啟的 Http2Stream 例項,可能會呼叫 http2session.destroy()。
如果指定,callback 函式將註冊為 'close' 事件的處理程式。
http2session.connecting#
- 型別:<boolean>
如果此 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 仍然開啟,它們也將被銷燬。
http2session.encrypted#
- 型別:<boolean> | <undefined>
如果 Http2Session 會話套接字尚未連線,則值為 undefined;如果 Http2Session 透過 TLSSocket 連線,則為 true;如果 Http2Session 連線到任何其他型別的套接字或流,則為 false。
http2session.goaway([code[, lastStreamID[, opaqueData]]])#
code<number> 一個 HTTP/2 錯誤碼lastStreamID<number> 最後處理的Http2Stream的數字 IDopaqueData<Buffer> | <TypedArray> | <DataView> 一個包含要在GOAWAY幀中攜帶的附加資料的TypedArray或DataView例項。
向連線的對等端傳送一個 GOAWAY 幀,但不關閉 Http2Session。
http2session.localSettings#
一個無原型的物件,描述此 Http2Session 的當前本地設定。本地設定僅限於此 Http2Session 例項。
http2session.originSet#
- 型別:<string[]> | <undefined>
如果 Http2Session 連線到 TLSSocket,originSet 屬性將返回一個 Array,其中包含 Http2Session 可能被視為權威的源列表。
originSet 屬性僅在使用安全的 TLS 連線時可用。
http2session.pendingSettingsAck#
- 型別:<boolean>
指示 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 引數,預設負載將是標記 PING 持續時間開始的 64 位時間戳(小端序)。
http2session.ref()#
在此 Http2Session 例項的底層 net.Socket 上呼叫 ref()。
http2session.remoteSettings#
一個無原型的物件,描述此 Http2Session 的當前遠端設定。遠端設定由已連線的 HTTP/2 對等端設定。
http2session.setLocalWindowSize(windowSize)#
windowSize<number>
設定本地端點的視窗大小。windowSize 是要設定的總視窗大小,而不是增量。
import { createServer } from 'node:http2';
const server = createServer();
const expectedWindowSize = 2 ** 20;
server.on('session', (session) => {
// Set local window size to be 2 ** 20
session.setLocalWindowSize(expectedWindowSize);
});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 當前狀態的雜項資訊。
- 型別:<Object>
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 Settings Object>callback<Function> 一旦會話連線或如果會話已連線,則立即呼叫的回撥函式。err<Error> | <null>settings<HTTP/2 Settings Object> 更新後的settings物件。duration<integer>
更新此 Http2Session 的當前本地設定,並向連線的 HTTP/2 對等端傳送一個新的 SETTINGS 幀。
一旦呼叫,當會話等待遠端對等端確認新設定時,http2session.pendingSettingsAck 屬性將為 true。
新設定將在收到 SETTINGS 確認並觸發 'localSettings' 事件後生效。在確認待處理期間可以傳送多個 SETTINGS 幀。
http2session.type#
- 型別:<number>
如果此 Http2Session 例項是伺服器,http2session.type 將等於 http2.constants.NGHTTP2_SESSION_SERVER;如果例項是客戶端,則等於 http2.constants.NGHTTP2_SESSION_CLIENT。
http2session.unref()#
在此 Http2Session 例項的底層 net.Socket 上呼叫 unref()。
類:ServerHttp2Session#
- 繼承自:<Http2Session>
serverhttp2session.altsvc(alt, originOrStream)#
alt<string> RFC 7838 中定義的替代服務配置的描述。originOrStream<number> | <string> | <URL> | <Object> 一個指定源的 URL 字串(或帶有origin屬性的Object),或一個活動Http2Stream的數字識別符號(由http2stream.id屬性給出)。
向連線的客戶端提交一個 ALTSVC 幀(由 RFC 7838 定義)。
import { createServer } from 'node:http2';
const server = 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);
});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 協議在主機 'example.org' 的 TCP/IP 埠 81 上可用。主機和埠必須包含在引號(")字元內。
可以指定多個替代方案,例如:'h2="example.org:81", h2=":82"'。
協議識別符號(示例中的 'h2')可以是任何有效的 ALPN 協議 ID。
Node.js 實現不驗證這些值的語法,並按使用者提供或從對等端接收的原樣傳遞。
serverhttp2session.origin(...origins)#
向連線的客戶端提交一個 ORIGIN 幀(由 RFC 8336 定義),以宣告伺服器能夠為其提供權威響應的一組源。
import { createSecureServer } from 'node:http2';
const options = getSecureOptionsSomehow();
const server = createSecureServer(options);
server.on('stream', (stream) => {
stream.respond();
stream.end('ok');
});
server.on('session', (session) => {
session.origin('https://example.com', 'https://example.org');
});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 選項:
import { createSecureServer } from 'node:http2';
const options = getSecureOptionsSomehow();
options.origins = ['https://example.com', 'https://example.org'];
const server = createSecureServer(options);
server.on('stream', (stream) => {
stream.respond();
stream.end('ok');
});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#
- 繼承自:<Http2Session>
事件:'altsvc'#
'altsvc' 事件在客戶端接收到 ALTSVC 幀時觸發。該事件將攜帶 ALTSVC 值、源和流 ID 觸發。如果 ALTSVC 幀中未提供 origin,則 origin 將是一個空字串。
import { connect } from 'node:http2';
const client = connect('https://example.org');
client.on('altsvc', (alt, origin, streamId) => {
console.log(alt);
console.log(origin);
console.log(streamId);
});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 將被更新以包含接收到的源。
import { connect } from 'node:http2';
const client = connect('https://example.org');
client.on('origin', (origins) => {
for (let n = 0; n < origins.length; n++)
console.log(origins[n]);
});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]);
});
'origin' 事件僅在使用安全的 TLS 連線時觸發。
clienthttp2session.request(headers[, options])#
-
headers<HTTP/2 Headers Object> | <HTTP/2 Raw Headers> -
options<Object>endStream<boolean> 如果Http2Stream的可寫端應初始關閉,則為true,例如在傳送不應期望有負載體的GET請求時。exclusive<boolean> 當為true且parent標識了一個父流時,建立的流將成為父流的唯一直接依賴項,所有其他現有依賴項都將成為新建立流的依賴項。預設值:false。parent<number> 指定新建立流所依賴的流的數字識別符號。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 時可用。
import { connect, constants } from 'node:http2';
const clientSession = connect('https://:1234');
const {
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
} = 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', () => { /* .. */ });
});const http2 = require('node:http2');
const clientSession = http2.connect('https://: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() 方法向對等端傳送尾部 Headers。
當設定了 options.waitForTrailers 時,Http2Stream 不會在傳輸最後一個 DATA 幀後自動關閉。使用者程式碼必須呼叫 http2stream.sendTrailers() 或 http2stream.close() 來關閉 Http2Stream。
當使用 AbortSignal 設定 options.signal,然後呼叫相應 AbortController 上的 abort 時,請求將觸發一個帶有 AbortError 錯誤的 'error' 事件。
:method 和 :path 偽頭未在 headers 中指定,它們分別預設為:
:method='GET':path=/
類:Http2Stream#
- 繼承自:<stream.Duplex>
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' 事件。如果呼叫 http2stream.destroy() 時傳遞了 Error 作為第一個引數,也可能觸發 'error' 事件。
在 Http2Stream 被銷燬後,http2stream.destroyed 屬性將為 true,http2stream.rstCode 屬性將指定 RST_STREAM 錯誤碼。一旦被銷燬,Http2Stream 例項將不再可用。
事件:'aborted'#
'aborted' 事件在 Http2Stream 例項在通訊中途被異常中止時觸發。其監聽器不接收任何引數。
'aborted' 事件僅在 Http2Stream 可寫端尚未結束時觸發。
事件:'close'#
'close' 事件在 Http2Stream 被銷燬時觸發。一旦此事件觸發,Http2Stream 例項將不再可用。
關閉流時使用的 HTTP/2 錯誤碼可以透過 http2stream.rstCode 屬性獲取。如果程式碼是除 NGHTTP2_NO_ERROR (0) 之外的任何值,則也已觸發了 'error' 事件。
事件:'frameError'#
'frameError' 事件在嘗試傳送幀時發生錯誤時觸發。呼叫時,處理函式將接收一個標識幀型別的整數引數和一個標識錯誤碼的整數引數。Http2Stream 例項將在 'frameError' 事件觸發後立即銷燬。
事件:'ready'#
'ready' 事件在 Http2Stream 已開啟、已分配 id 並可使用時觸發。監聽器不接收任何引數。
事件:'timeout'#
在使用 http2stream.setTimeout() 設定的毫秒數內,如果此 Http2Stream 未收到任何活動,則會觸發 'timeout' 事件。其監聽器不接收任何引數。
事件:'trailers'#
headers<HTTP/2 Headers Object> 描述 Headers 的物件flags<number> 相關的數字標誌
'trailers' 事件在接收到與尾部頭欄位關聯的頭塊時觸發。監聽器回撥函式將接收到 HTTP/2 Headers 物件和與頭關聯的標誌。
如果在接收到尾部資料之前呼叫了 http2stream.end(),並且沒有讀取或監聽傳入的資料,則可能不會觸發此事件。
stream.on('trailers', (headers, flags) => {
console.log(headers);
});
事件:'wantTrailers'#
當 Http2Stream 已將最後一個 DATA 幀排隊傳送,並且 Http2Stream 準備好傳送尾部頭時,會觸發 'wantTrailers' 事件。在發起請求或響應時,必須設定 waitForTrailers 選項才能觸發此事件。
http2stream.close(code[, callback])#
code<number> 標識錯誤碼的無符號 32 位整數。預設值:http2.constants.NGHTTP2_NO_ERROR(0x00)。callback<Function> 一個可選的函式,註冊用於監聽'close'事件。
透過向連線的 HTTP/2 對等端傳送一個 RST_STREAM 幀來關閉 Http2Stream 例項。
http2stream.endAfterHeaders#
- 型別:<boolean>
如果接收到的請求或響應 HEADERS 幀中設定了 END_STREAM 標誌,則設定為 true,表示不應再接收額外資料,並且 Http2Stream 的可讀端將被關閉。
http2stream.rstCode#
- 型別:<number>
當 Http2Stream 在接收到來自連線對等端的 RST_STREAM 幀、呼叫 http2stream.close() 或 http2stream.destroy() 後被銷燬時,設定為報告的 RST_STREAM 錯誤碼。如果 Http2Stream 尚未關閉,則為 undefined。
http2stream.session#
對此 Http2Stream 所屬的 Http2Session 例項的引用。在 Http2Stream 例項被銷燬後,該值將為 undefined。
http2stream.setTimeout(msecs, callback)#
msecs<number>callback<Function>
import { connect, constants } from 'node:http2';
const client = connect('http://example.org:8000');
const { NGHTTP2_CANCEL } = constants;
const req = client.request({ ':path': '/' });
// Cancel the stream if there's no activity after 5 seconds
req.setTimeout(5000, () => req.close(NGHTTP2_CANCEL));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 當前狀態的雜項資訊。
- 型別:<Object>
localWindowSize<number> 連線的對等端可以為此Http2Stream傳送的位元組數,而無需接收WINDOW_UPDATE。state<number> 一個標誌,指示由nghttp2確定的Http2Stream的底層當前狀態。localClose<number> 如果此Http2Stream已在本地關閉,則為1。remoteClose<number> 如果此Http2Stream已在遠端關閉,則為1。sumDependencyWeight<number> 舊版屬性,始終設定為0。weight<number> 舊版屬性,始終設定為16。
此 Http2Stream 的當前狀態。
http2stream.sendTrailers(headers)#
headers<HTTP/2 Headers Object>
向連線的 HTTP/2 對等端傳送一個尾部 HEADERS 幀。此方法將導致 Http2Stream 立即關閉,並且只能在 'wantTrailers' 事件觸發後呼叫。當傳送請求或傳送響應時,必須設定 options.waitForTrailers 選項,以便在最後一個 DATA 幀之後保持 Http2Stream 開啟,從而可以傳送尾部資料。
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream) => {
stream.respond(undefined, { waitForTrailers: true });
stream.on('wantTrailers', () => {
stream.sendTrailers({ xyz: 'abc' });
});
stream.end('Hello World');
});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#
- 繼承自 <Http2Stream>
ClientHttp2Stream 類是 Http2Stream 的擴充套件,專門用於 HTTP/2 客戶端。客戶端上的 Http2Stream 例項提供諸如 'response' 和 'push' 等僅與客戶端相關的事件。
事件:'continue'#
當伺服器傳送 100 Continue 狀態時觸發,通常是因為請求包含了 Expect: 100-continue。這是一個指示客戶端應該傳送請求體的指令。
事件:'headers'#
headers<HTTP/2 Headers Object>flags<number>rawHeaders<HTTP/2 Raw Headers>
'headers' 事件在接收到流的附加頭塊時觸發,例如當接收到 1xx 資訊頭塊時。監聽器回撥函式會接收到 HTTP/2 Headers 物件、與頭關聯的標誌以及原始格式的頭(參見 HTTP/2 原始 Headers)。
stream.on('headers', (headers, flags) => {
console.log(headers);
});
事件:'push'#
headers<HTTP/2 Headers Object>flags<number>
'push' 事件在接收到伺服器推送流的響應頭時觸發。監聽器回撥函式會接收到 HTTP/2 Headers 物件和與頭關聯的標誌。
stream.on('push', (headers, flags) => {
console.log(headers);
});
事件:'response'#
headers<HTTP/2 Headers Object>flags<number>rawHeaders<HTTP/2 Raw Headers>
'response' 事件在此流從連線的 HTTP/2 伺服器接收到響應 HEADERS 幀時觸發。監聽器將接收三個引數:一個包含接收到的 HTTP/2 Headers 物件的 Object,與頭關聯的標誌,以及原始格式的頭(參見 HTTP/2 原始 Headers)。
import { connect } from 'node:http2';
const client = connect('https://');
const req = client.request({ ':path': '/' });
req.on('response', (headers, flags) => {
console.log(headers[':status']);
});const http2 = require('node:http2');
const client = http2.connect('https://');
const req = client.request({ ':path': '/' });
req.on('response', (headers, flags) => {
console.log(headers[':status']);
});
類:ServerHttp2Stream#
- 繼承自:<Http2Stream>
ServerHttp2Stream 類是 Http2Stream 的擴充套件,專門用於 HTTP/2 伺服器。伺服器上的 Http2Stream 例項提供了諸如 http2stream.pushStream() 和 http2stream.respond() 等僅與伺服器相關的方法。
http2stream.additionalHeaders(headers)#
headers<HTTP/2 Headers Object>
向連線的 HTTP/2 對等端傳送一個附加的資訊性 HEADERS 幀。
http2stream.pushAllowed#
- 型別:<boolean>
只讀屬性,對映到遠端客戶端最新 SETTINGS 幀的 SETTINGS_ENABLE_PUSH 標誌。如果遠端對等端接受推送流,則為 true,否則為 false。在同一個 Http2Session 中的每個 Http2Stream 的設定都是相同的。
http2stream.pushStream(headers[, options], callback)#
headers<HTTP/2 Headers Object>options<Object>callback<Function> 推送流啟動後呼叫的回撥函式。err<Error>pushStream<ServerHttp2Stream> 返回的pushStream物件。headers<HTTP/2 Headers Object>pushStream啟動時使用的頭物件。
啟動一個推送流。回撥函式被呼叫時,會將為推送流建立的新的 Http2Stream 例項作為第二個引數傳遞,或者將一個 Error 作為第一個引數傳遞。
import { createServer } from 'node:http2';
const server = 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');
});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 Headers Object> | <HTTP/2 Raw Headers>options<Object>
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 });
stream.end('some data');
});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。
import { createServer } from 'node:http2';
const server = 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');
});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 Headers Object>options<Object>statCheck<Function>waitForTrailers<boolean> 當為true時,Http2Stream將在傳送最後一個DATA幀後觸發'wantTrailers'事件。offset<number> 開始讀取的偏移位置。length<number> 從 fd 傳送的資料量。
啟動一個響應,其資料從給定的檔案描述符中讀取。不對給定的檔案描述符進行驗證。如果在嘗試使用檔案描述符讀取資料時發生錯誤,Http2Stream 將使用標準的 INTERNAL_ERROR 程式碼透過 RST_STREAM 幀關閉。
使用此方法時,Http2Stream 物件的 Duplex 介面將自動關閉。
import { createServer } from 'node:http2';
import { openSync, fstatSync, closeSync } from 'node:fs';
const server = createServer();
server.on('stream', (stream) => {
const fd = openSync('/some/file', 'r');
const stat = 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', () => closeSync(fd));
});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 時,Http2Stream 在傳輸最後一個 DATA 幀時不會自動關閉。使用者程式碼必須呼叫 http2stream.sendTrailers() 或 http2stream.close() 來關閉 Http2Stream。
import { createServer } from 'node:http2';
import { openSync, fstatSync, closeSync } from 'node:fs';
const server = createServer();
server.on('stream', (stream) => {
const fd = openSync('/some/file', 'r');
const stat = 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', () => closeSync(fd));
});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 Headers Object>options<Object>statCheck<Function>onError<Function> 在傳送前發生錯誤時呼叫的回撥函式。waitForTrailers<boolean> 當為true時,Http2Stream將在傳送最後一個DATA幀後觸發'wantTrailers'事件。offset<number> 開始讀取的偏移位置。length<number> 從 fd 傳送的資料量。
將一個常規檔案作為響應傳送。path 必須指定一個常規檔案,否則將在 Http2Stream 物件上觸發 'error' 事件。
使用此方法時,Http2Stream 物件的 Duplex 介面將自動關閉。
可以指定可選的 options.statCheck 函式,讓使用者程式碼有機會根據給定檔案的 fs.Stat 詳細資訊設定額外的內容頭。
如果在嘗試讀取檔案資料時發生錯誤,Http2Stream 將使用標準的 INTERNAL_ERROR 程式碼透過 RST_STREAM 幀關閉。如果定義了 onError 回撥,則會呼叫它。否則流將被銷燬。
使用檔案路徑的示例:
import { createServer } from 'node:http2';
const server = 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 });
});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 來取消傳送操作。例如,一個條件請求可以檢查 stat 結果來確定檔案是否已被修改,以返回一個適當的 304 響應。
import { createServer } from 'node:http2';
const server = 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 });
});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 時,Http2Stream 不會在傳輸最後一個 DATA 幀後自動關閉。使用者程式碼必須呼叫 http2stream.sendTrailers() 或 http2stream.close() 來關閉 Http2Stream。
import { createServer } from 'node:http2';
const server = 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' });
});
});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。
事件:'sessionError'#
error<Error>session<ServerHttp2Session>
當與 Http2Server 關聯的 Http2Session 物件觸發 'error' 事件時,會觸發 'sessionError' 事件。
事件:'stream'#
stream<Http2Stream> 對該流的引用headers<HTTP/2 Headers Object> 描述 Headers 的物件flags<number> 相關的數字標誌rawHeaders<HTTP/2 Raw Headers> 包含原始 Headers 的陣列
當與伺服器關聯的 Http2Session 觸發了 'stream' 事件時,會觸發 'stream' 事件。
另請參閱 Http2Session 的 'stream' 事件。
import { createServer, constants } from 'node:http2';
const {
HTTP2_HEADER_METHOD,
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
HTTP2_HEADER_CONTENT_TYPE,
} = constants;
const server = 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');
});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,該 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 Object>
用於使用提供的設定更新伺服器。
對於無效的 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> 描述 Headers 的物件flags<number> 相關的數字標誌rawHeaders<HTTP/2 Raw Headers> 包含原始 Headers 的陣列
當與伺服器關聯的 Http2Session 觸發了 'stream' 事件時,會觸發 'stream' 事件。
另請參閱 Http2Session 的 'stream' 事件。
import { createSecureServer, constants } from 'node:http2';
const {
HTTP2_HEADER_METHOD,
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS,
HTTP2_HEADER_CONTENT_TYPE,
} = constants;
const options = getOptionsSomehow();
const server = 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');
});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 擴充套件時才觸發此事件。如果客戶端傳送的 ALPN 擴充套件不包含 HTTP/2(或在 allowHTTP1 為 true 時不包含 HTTP/1.1),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 Object>
用於使用提供的設定更新伺服器。
對於無效的 settings 值,會丟擲 ERR_HTTP2_INVALID_SETTING_VALUE。
對於無效的 settings 引數,會丟擲 ERR_INVALID_ARG_TYPE。
http2.createServer([options][, onRequestHandler])#
options<Object>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 Settings Object> 連線時傳送給遠端對端的初始設定。streamResetBurst<number> 和streamResetRate<number> 設定傳入流重置(RST_STREAM 幀)的速率限制。必須同時設定這兩個設定才能生效,預設值分別為 1000 和 33。remoteCustomSettings<Array> 整數值陣列,用於確定設定型別,這些型別包含在接收到的 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<number> 指定當觸發'unknownProtocol'事件時伺服器應等待的超時時間(毫秒)。如果到那時套接字尚未被銷燬,伺服器將銷燬它。預設值:10000。strictFieldWhitespaceValidation<boolean> 如果為true,則根據 RFC-9113 對 HTTP/2 標頭欄位名稱和值進行嚴格的前導和尾隨空格驗證。預設值:true。...options<Object> 可以提供任何net.createServer()選項。
onRequestHandler<Function> 請參閱相容性 API- 返回:<Http2Server>
返回一個建立和管理 Http2Session 例項的 net.Server 例項。
由於沒有已知的瀏覽器支援未加密的 HTTP/2,因此在與瀏覽器客戶端通訊時必須使用 http2.createSecureServer()。
import { createServer } from 'node:http2';
// Create an unencrypted HTTP/2 server.
// Since there are no browsers known that support
// unencrypted HTTP/2, the use of `createSecureServer()`
// is necessary when communicating with browser clients.
const server = 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);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<Object>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 Settings Object> 連線時傳送給遠端對端的初始設定。streamResetBurst<number> 和streamResetRate<number> 設定傳入流重置(RST_STREAM 幀)的速率限制。必須同時設定這兩個設定才能生效,預設值分別為 1000 和 33。remoteCustomSettings<Array> 整數值陣列,用於確定設定型別,這些型別包含在接收到的 remoteSettings 的customSettings屬性中。有關允許的設定型別的更多資訊,請參閱Http2Settings物件的customSettings屬性。...options<Object> 可以提供任何tls.createServer()選項。對於伺服器,通常需要身份選項(pfx或key/cert)。origins<string[]> 一個源字串陣列,在建立新的伺服器Http2Session後立即在ORIGIN幀內傳送。unknownProtocolTimeout<number> 指定當觸發'unknownProtocol'事件時伺服器應等待的超時時間(毫秒)。如果到那時套接字尚未被銷燬,伺服器將銷燬它。預設值:10000。strictFieldWhitespaceValidation<boolean> 如果為true,則根據 RFC-9113 對 HTTP/2 標頭欄位名稱和值進行嚴格的前導和尾隨空格驗證。預設值:true。
onRequestHandler<Function> 請參閱相容性 API- 返回:<Http2SecureServer>
返回一個建立和管理 Http2Session 例項的 tls.Server 例項。
import { createSecureServer } from 'node:http2';
import { readFileSync } from 'node:fs';
const options = {
key: readFileSync('server-key.pem'),
cert: readFileSync('server-cert.pem'),
};
// Create a secure HTTP/2 server
const server = 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);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 伺服器。它必須是具有http://或https://字首、主機名和 IP 埠(如果使用非預設埠)的最小有效 URL 形式。URL 中的 Userinfo(使用者 ID 和密碼)、路徑、查詢字串和片段詳細資訊將被忽略。options<Object>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 Settings Object> 連線時傳送給遠端對端的初始設定。remoteCustomSettings<Array> 整數值陣列,用於確定設定型別,這些型別包含在接收到的 remoteSettings 的CustomSettings屬性中。有關允許的設定型別的更多資訊,請參閱Http2Settings物件的CustomSettings屬性。createConnection<Function> 一個可選的回撥函式,接收傳遞給connect的URL例項和options物件,並返回任何將用作此會話連線的Duplex流。...options<Object> 可以提供任何net.connect()或tls.connect()選項。unknownProtocolTimeout<number> 指定當觸發'unknownProtocol'事件時伺服器應等待的超時時間(毫秒)。如果到那時套接字尚未被銷燬,伺服器將銷燬它。預設值:10000。strictFieldWhitespaceValidation<boolean> 如果為true,則根據 RFC-9113 對 HTTP/2 標頭欄位名稱和值進行嚴格的前導和尾隨空格驗證。預設值:true。
listener<Function> 將作為'connect'事件的一次性監聽器註冊。- 返回:<ClientHttp2Session>
返回一個 ClientHttp2Session 例項。
import { connect } from 'node:http2';
const client = connect('https://:1234');
/* Use the client */
client.close();const http2 = require('node:http2');
const client = http2.connect('https://: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 | 保持冷靜(Enhance Your Calm) | 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 Settings Object>- 返回:<Buffer>
返回一個 Buffer 例項,其中包含根據 HTTP/2 規範指定的給定 HTTP/2 設定的序列化表示。這旨在與 HTTP2-Settings 標頭欄位一起使用。
import { getPackedSettings } from 'node:http2';
const packed = getPackedSettings({ enablePush: false });
console.log(packed.toString('base64'));
// Prints: AAIAAAAAconst 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 Settings Object>
返回一個 HTTP/2 設定物件,其中包含從給定 Buffer 反序列化的設定,該 Buffer 由 http2.getPackedSettings() 生成。
http2.performServerHandshake(socket[, options])#
socket<stream.Duplex>options<Object> 可以提供任何http2.createServer()選項。- 返回:<ServerHttp2Session>
從現有套接字建立 HTTP/2 伺服器會話。
標頭物件#
標頭表示為 JavaScript 物件上的自有屬性。屬性鍵將被序列化為小寫。屬性值應該是字串(如果不是,它們將被強制轉換為字串)或字串陣列(以便為每個標頭欄位傳送多個值)。
const headers = {
':status': '200',
'content-type': 'text-plain',
'ABC': ['has', 'more', 'than', 'one', 'value'],
};
stream.respond(headers);
傳遞給回撥函式的標頭物件將具有 null 原型。這意味著像 Object.prototype.toString() 和 Object.prototype.hasOwnProperty() 這樣的普通 JavaScript 物件方法將不起作用。
對於傳入的標頭
: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標頭,值會用 '; ' 連線在一起。 - 對於所有其他標頭,值會用 ', ' 連線在一起。
import { createServer } from 'node:http2';
const server = createServer();
server.on('stream', (stream, headers) => {
console.log(headers[':path']);
console.log(headers.ABC);
});const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream, headers) => {
console.log(headers[':path']);
console.log(headers.ABC);
});
原始標頭#
在某些 API 中,除了物件格式外,標頭也可以作為原始的扁平陣列傳遞或訪問,保留了排序和重複鍵的細節,以匹配原始傳輸格式。
在這種格式中,鍵和值在同一個列表中。它*不是*一個元組列表。因此,偶數偏移量是鍵值,奇數偏移量是相關的值。重複的標頭不會被合併,因此每個鍵值對將單獨出現。
這對於諸如代理之類的情況可能很有用,其中現有標頭應完全按接收到的方式轉發,或者當標頭已經以原始格式可用時作為效能最佳化。
const rawHeaders = [
':status',
'404',
'content-type',
'text/plain',
];
stream.respond(rawHeaders);
敏感標頭#
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 標頭,此標誌是自動設定的。
此屬性也為接收到的標頭設定。它將包含所有標記為敏感的標頭的名稱,包括那些自動標記的標頭。
對於原始標頭,這仍然應該作為陣列上的一個屬性來設定,比如 rawHeadersArray[http2.sensitiveHeaders] = ['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 定義的“擴充套件連線協議”。此設定僅在由伺服器傳送時有意義。一旦為給定的Http2Session啟用了enableConnectProtocol設定,就無法停用它。預設值:false。customSettings<Object> 指定了尚未在 node 和底層庫中實現的附加設定。物件的鍵定義了設定型別的數值(如 [RFC 7540] 建立的“HTTP/2 SETTINGS”登錄檔中所定義),值則為設定的實際數值。設定型別必須是 1 到 2^16-1 範圍內的整數。它不應該是 node 已經處理的設定型別,即目前應大於 6,儘管這不是一個錯誤。值必須是 0 到 2^32-1 範圍內的無符號整數。目前,最多支援 10 個自定義設定。它僅支援傳送 SETTINGS,或接收在伺服器或客戶端物件的remoteCustomSettings選項中指定的設定值。不要將customSettings機制用於與原生處理的設定介面混合的設定 ID,以防將來 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/2 實現對 HTTP 標頭名稱和值中的無效字元的處理比 HTTP/1 實現更嚴格。
標頭欄位名稱*不區分大小寫*,並在網路上傳輸時嚴格作為小寫字串。Node.js 提供的 API 允許將標頭名稱設定為混合大小寫字串(例如 Content-Type),但在傳輸時會將其轉換為小寫(例如 content-type)。
標頭欄位名稱*必須僅*包含以下一個或多個 ASCII 字元:a-z、A-Z、0-9、!、#、$、%、&、'、*、+、-、.、^、_、`(反引號)、| 和 ~。
在 HTTP 標頭欄位名稱中使用無效字元將導致流因協議錯誤而關閉。
標頭欄位值的處理更為寬鬆,但*不應*包含換行符或回車符,並且*應*限制為 US-ASCII 字元,根據 HTTP 規範的要求。
客戶端上的推送流#
要在客戶端接收推送流,請在 ClientHttp2Session 上為 'stream' 事件設定一個監聽器
import { connect } from 'node:http2';
const client = connect('https://');
client.on('stream', (pushedStream, requestHeaders) => {
pushedStream.on('push', (responseHeaders) => {
// Process response headers
});
pushedStream.on('data', (chunk) => { /* handle pushed data */ });
});
const req = client.request({ ':path': '/' });const http2 = require('node:http2');
const client = http2.connect('https://');
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 伺服器
import { createServer } from 'node:net';
const server = createServer((socket) => {
let name = '';
socket.setEncoding('utf8');
socket.on('data', (chunk) => name += chunk);
socket.on('end', () => socket.end(`hello ${name}`));
});
server.listen(8000);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 代理
import { createServer, constants } from 'node:http2';
const { NGHTTP2_REFUSED_STREAM, NGHTTP2_CONNECT_ERROR } = constants;
import { connect } from 'node:net';
const proxy = 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 = connect(auth.port, auth.hostname, () => {
stream.respond();
socket.pipe(stream);
stream.pipe(socket);
});
socket.on('error', (error) => {
stream.close(NGHTTP2_CONNECT_ERROR);
});
});
proxy.listen(8001);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 客戶端
import { connect, constants } from 'node:http2';
const client = connect('https://: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[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');const http2 = require('node:http2');
const client = http2.connect('https://: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 協議
import { createServer } from 'node:http2';
const settings = { enableConnectProtocol: true };
const server = createServer({ settings });const http2 = require('node:http2');
const settings = { enableConnectProtocol: true };
const server = http2.createServer({ settings });
一旦客戶端從伺服器接收到指示可以使用擴充套件 CONNECT 的 SETTINGS 幀,它就可以傳送使用 ':protocol' HTTP/2 偽標頭的 CONNECT 請求
import { connect } from 'node:http2';
const client = connect('https://:8080');
client.on('remoteSettings', (settings) => {
if (settings.enableConnectProtocol) {
const req = client.request({ ':method': 'CONNECT', ':protocol': 'foo' });
// ...
}
});const http2 = require('node:http2');
const client = http2.connect('https://: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 伺服器
import { createServer } from 'node:http2';
const server = 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');
});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 的更高階功能。
以下示例建立了一個同時支援兩種協議的伺服器
import { createSecureServer } from 'node:http2';
import { readFileSync } from 'node:fs';
const cert = readFileSync('./cert.pem');
const key = readFileSync('./key.pem');
const server = createSecureServer(
{ cert, key, allowHTTP1: true },
onRequest,
).listen(8000);
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,
}));
}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#
- 擴充套件自:<stream.Readable>
Http2ServerRequest 物件由 http2.Server 或 http2.SecureServer 建立,並作為第一個引數傳遞給 'request' 事件。它可用於訪問請求狀態、標頭和資料。
事件:'aborted'#
每當 Http2ServerRequest 例項在通訊中途異常中止時,就會觸發 'aborted' 事件。
只有在 Http2ServerRequest 的可寫端尚未結束時,才會觸發 'aborted' 事件。
事件:'close'#
表示底層的 Http2Stream 已關閉。與 'end' 一樣,此事件每個響應只發生一次。
request.authority#
- 型別:<string>
請求的 authority 偽標頭欄位。因為 HTTP/2 允許請求設定 :authority 或 host,所以如果存在 req.headers[':authority'],則此值派生自它。否則,它派生自 req.headers['host']。
request.destroy([error])#
error<Error>
在接收到 Http2ServerRequest 的 Http2Stream 上呼叫 destroy()。如果提供了 error,則會觸發一個 'error' 事件,並且 error 會作為引數傳遞給該事件的任何監聽器。
如果流已經被銷燬,則不執行任何操作。
request.headers#
- 型別:<Object>
請求/響應的標頭物件。
標頭名稱和值的鍵值對。標頭名稱是小寫的。
// 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#
- 型別:<string>
對於伺服器請求,是客戶端傳送的 HTTP 版本。對於客戶端響應,是所連線伺服器的 HTTP 版本。返回 '2.0'。
同時 message.httpVersionMajor 是第一個整數,message.httpVersionMinor 是第二個。
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.setTimeout(msecs, callback)#
msecs<number>callback<Function>- 返回:<http2.Http2ServerRequest>
將 Http2Stream 的超時值設定為 msecs。如果提供了回撥,則將其新增為響應物件上 'timeout' 事件的監聽器。
如果沒有為請求、響應或伺服器新增 'timeout' 監聽器,那麼當 Http2Stream 超時時,它們將被銷燬。如果為請求、響應或伺服器的 'timeout' 事件分配了處理程式,則必須顯式處理超時的套接字。
request.socket#
返回一個充當 net.Socket(或 tls.TLSSocket)的 Proxy 物件,但會根據 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.url#
- 型別:<string>
請求 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'#
表示底層的 Http2Stream 在 response.end() 被呼叫或能夠重新整理之前已終止。
事件:'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.createPushResponse(headers, callback)#
headers<HTTP/2 Headers Object> 描述 Headers 的物件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。- 型別:<boolean>
布林值,指示響應是否已完成。初始為 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.removeHeader(name)#
name<string>
刪除已排隊等待隱式傳送的標頭。
response.removeHeader('Content-Encoding');
response.sendDate#
- 型別:<boolean>
當為 true 時,如果 Date 標頭尚未出現在標頭中,則會自動生成併發送在響應中。預設為 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#
返回一個充當 net.Socket(或 tls.TLSSocket)的 Proxy 物件,但會根據 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 和套接字。
所有其他互動將直接路由到套接字。
import { createServer } from 'node:http2';
const server = 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);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#
- 型別:<number>
當使用隱式標頭時(不顯式呼叫 response.writeHead()),此屬性控制在標頭重新整理時將傳送給客戶端的狀態碼。
response.statusCode = 404;
在響應標頭髮送給客戶端後,此屬性指示已傳送的狀態碼。
response.writableEnded#
- 型別:<boolean>
在 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<HTTP/2 Headers Object> | <HTTP/2 Raw 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 是否與正在傳輸的正文長度相等。但是,在接收訊息時,Node.js 會自動拒絕 Content-Length 與實際有效載荷大小不匹配的訊息。
在呼叫 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 例項的基本效能指標。
import { PerformanceObserver } from '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'] });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> 從PerformanceEntrystartTime到接收到第一個DATA幀之間經過的毫秒數。timeToFirstByteSent<number> 從PerformanceEntrystartTime到傳送第一個DATA幀之間經過的毫秒數。timeToFirstHeader<number> 從PerformanceEntrystartTime到接收到第一個標頭之間經過的毫秒數。
如果 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),則需要自己實現任何回退行為。