HTTP/2#

穩定性:2 - 穩定

原始碼:lib/http2.js

node:http2 模組提供了 HTTP/2 協議的實現。可以透過以下方式訪問:

const http2 = require('node:http2'); 

確定加密支援是否可用#

Node.js 在構建時可能不包含對 node:crypto 模組的支援。在這種情況下,嘗試從 node:http2import 或呼叫 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#

http2.Http2Session 類的例項表示 HTTP/2 客戶端和伺服器之間的活動通訊會話。使用者程式碼應該直接構造該類的例項。

每個 Http2Session 例項的行為會根據其作為伺服器還是客戶端執行而略有不同。http2session.type 屬性可用於確定 Http2Session 的執行模式。在伺服器端,使用者程式碼很少需要直接操作 Http2Session 物件,大多數操作通常透過與 Http2ServerHttp2Stream 物件互動來完成。

使用者程式碼不會直接建立 Http2Session 例項。伺服器端的 Http2Session 例項由 Http2Server 例項在接收到新的 HTTP/2 連線時建立。客戶端的 Http2Session 例項則透過 http2.connect() 方法建立。

Http2Session 和套接字#

每個 Http2Session 例項在建立時都與一個 net.Sockettls.TLSSocket 相關聯。當 SocketHttp2Session 被銷燬時,兩者都會被銷燬。

由於 HTTP/2 協議有特定的序列化和處理要求,不建議使用者程式碼從繫結到 Http2SessionSocket 例項中讀取資料或向其寫入資料。這樣做可能會使 HTTP/2 會話進入不確定狀態,導致會話和套接字變得無法使用。

一旦 Socket 被繫結到 Http2Session,使用者程式碼應完全依賴於 Http2Session 的 API。

事件:'close'#

'close' 事件在 Http2Session 被銷燬後觸發。其監聽器不接收任何引數。

事件:'connect'#

'connect' 事件在 Http2Session 成功連線到遠端對等端並且可以開始通訊時觸發。

使用者程式碼通常不會直接監聽此事件。

事件:'error'#

'error' 事件在處理 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'#

'localSettings' 事件在收到確認 SETTINGS 幀時觸發。

當使用 http2session.settings() 提交新設定時,修改後的設定直到 'localSettings' 事件觸發後才會生效。

session.settings({ enablePush: false });

session.on('localSettings', (settings) => {
  /* Use the new settings */
}); 
事件:'ping'#
  • payload <Buffer> PING 幀的 8 位元組負載

'ping' 事件在從連線的對等端接收到 PING 幀時觸發。

事件:'remoteSettings'#

'remoteSettings' 事件在從連線的對等端接收到新的 SETTINGS 幀時觸發。

session.on('remoteSettings', (settings) => {
  /* Use the new settings */
}); 
事件:'stream'#

'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.Servertls.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#

如果 Http2Session 尚未連線到套接字,則該值為 undefined;如果 Http2Session 未連線到 TLSSocket,則為 h2c;否則將返回所連線的 TLSSocket 自身的 alpnProtocol 屬性值。

http2session.close([callback])#

平滑地關閉 Http2Session,允許任何現有流自行完成,並阻止建立新的 Http2Stream 例項。一旦關閉,如果沒有開啟的 Http2Stream 例項,可能會呼叫 http2session.destroy()

如果指定,callback 函式將註冊為 'close' 事件的處理程式。

http2session.closed#

如果此 Http2Session 例項已關閉,則為 true,否則為 false

http2session.connecting#

如果此 Http2Session 例項仍在連線中,則為 true,在觸發 connect 事件和/或呼叫 http2.connect 回撥之前將設定為 false

http2session.destroy([error][, code])#
  • error <Error> 如果 Http2Session 因錯誤而被銷燬,則為一個 Error 物件。
  • code <number> 在最終的 GOAWAY 幀中傳送的 HTTP/2 錯誤碼。如果未指定,且 error 不為 undefined,則預設為 INTERNAL_ERROR,否則預設為 NO_ERROR

立即終止 Http2Session 及其關聯的 net.Sockettls.TLSSocket

一旦被銷燬,Http2Session 將觸發 'close' 事件。如果 error 不為 undefined,則會在 'close' 事件之前立即觸發 'error' 事件。

如果與 Http2Session 關聯的任何 Http2Streams 仍然開啟,它們也將被銷燬。

http2session.destroyed#

如果此 Http2Session 例項已被銷燬且不應再使用,則為 true,否則為 false

http2session.encrypted#

如果 Http2Session 會話套接字尚未連線,則值為 undefined;如果 Http2Session 透過 TLSSocket 連線,則為 true;如果 Http2Session 連線到任何其他型別的套接字或流,則為 false

http2session.goaway([code[, lastStreamID[, opaqueData]]])#
  • code <number> 一個 HTTP/2 錯誤碼
  • lastStreamID <number> 最後處理的 Http2Stream 的數字 ID
  • opaqueData <Buffer> | <TypedArray> | <DataView> 一個包含要在 GOAWAY 幀中攜帶的附加資料的 TypedArrayDataView 例項。

向連線的對等端傳送一個 GOAWAY 幀,但關閉 Http2Session

http2session.localSettings#

一個無原型的物件,描述此 Http2Session 的當前本地設定。本地設定僅限於 Http2Session 例項。

http2session.originSet#

如果 Http2Session 連線到 TLSSocketoriginSet 屬性將返回一個 Array,其中包含 Http2Session 可能被視為權威的源列表。

originSet 屬性僅在使用安全的 TLS 連線時可用。

http2session.pendingSettingsAck#

指示 Http2Session 當前是否正在等待已傳送的 SETTINGS 幀的確認。在呼叫 http2session.settings() 方法後將為 true。一旦所有已傳送的 SETTINGS 幀都得到確認,將變為 false

http2session.ping([payload, ]callback)#

向連線的 HTTP/2 對等端傳送一個 PING 幀。必須提供一個 callback 函式。如果 PING 已傳送,該方法返回 true,否則返回 false

未完成(未確認)的 ping 的最大數量由 maxOutstandingPings 配置選項決定。預設最大值為 10。

如果提供,payload 必須是包含 8 位元組資料的 BufferTypedArrayDataView,這些資料將與 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 是要設定的總視窗大小,而不是增量。

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)#

用於設定一個回撥函式,當 Http2Sessionmsecs 毫秒內沒有任何活動時呼叫。給定的 callback 將作為 'timeout' 事件的監聽器註冊。

http2session.socket#

返回一個 Proxy 物件,其行為類似於 net.Socket(或 tls.TLSSocket),但將可用方法限制為可安全用於 HTTP/2 的方法。

destroyemitendpausereadresumewrite 將丟擲一個程式碼為 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> 最近接收到 HEADERSDATA 幀的 Http2Stream 的數字 ID。
    • remoteWindowSize <number>Http2Session 在不接收 WINDOW_UPDATE 的情況下可以傳送的位元組數。
    • outboundQueueSize <number>Http2Session 的出站佇列中當前幀的數量。
    • deflateDynamicTableSize <number> 出站頭壓縮狀態表的當前大小(以位元組為單位)。
    • inflateDynamicTableSize <number> 入站頭壓縮狀態表的當前大小(以位元組為單位)。

一個描述此 Http2Session 當前狀態的物件。

http2session.settings([settings][, callback])#

更新此 Http2Session 的當前本地設定,並向連線的 HTTP/2 對等端傳送一個新的 SETTINGS 幀。

一旦呼叫,當會話等待遠端對等端確認新設定時,http2session.pendingSettingsAck 屬性將為 true

新設定將在收到 SETTINGS 確認並觸發 'localSettings' 事件後生效。在確認待處理期間可以傳送多個 SETTINGS 幀。

http2session.type#

如果此 Http2Session 例項是伺服器,http2session.type 將等於 http2.constants.NGHTTP2_SESSION_SERVER;如果例項是客戶端,則等於 http2.constants.NGHTTP2_SESSION_CLIENT

http2session.unref()#

在此 Http2Session 例項的底層 net.Socket 上呼叫 unref()

類:ServerHttp2Session#

serverhttp2session.altsvc(alt, originOrStream)#
  • alt <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#

事件:'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'#

'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> 當為 trueparent 標識了一個父流時,建立的流將成為父流的唯一直接依賴項,所有其他現有依賴項都將成為新建立流的依賴項。預設值:false
    • parent <number> 指定新建立流所依賴的流的數字識別符號。
    • waitForTrailers <boolean> 當為 true 時,Http2Stream 將在傳送最後一個 DATA 幀後觸發 'wantTrailers' 事件。
    • signal <AbortSignal> 一個可用於中止正在進行的請求的 AbortSignal。
  • 返回:<ClientHttp2Stream>

僅對於 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#

Http2Stream 類的每個例項代表一個透過 Http2Session 例項的雙向 HTTP/2 通訊流。任何單個 Http2Session 在其生命週期內最多可以有 231-1 個 Http2Stream 例項。

使用者程式碼不會直接構造 Http2Stream 例項。相反,這些例項由 Http2Session 例項建立、管理並提供給使用者程式碼。在伺服器上,Http2Stream 例項要麼響應傳入的 HTTP 請求而建立(並透過 'stream' 事件交給使用者程式碼),要麼響應對 http2stream.pushStream() 方法的呼叫而建立。在客戶端,Http2Stream 例項在呼叫 http2session.request() 方法時建立並返回,或響應傳入的 'push' 事件而建立。

Http2Stream 類是 ServerHttp2StreamClientHttp2Stream 類的基類,它們分別專用於伺服器端和客戶端。

所有 Http2Stream 例項都是 Duplex 流。DuplexWritable 端用於向連線的對等端傳送資料,而 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' 事件。由於 Http2Streamstream.Duplex 的例項,如果流資料當前正在流動,也會觸發 'end' 事件。如果呼叫 http2stream.destroy() 時傳遞了 Error 作為第一個引數,也可能觸發 'error' 事件。

Http2Stream 被銷燬後,http2stream.destroyed 屬性將為 truehttp2stream.rstCode 屬性將指定 RST_STREAM 錯誤碼。一旦被銷燬,Http2Stream 例項將不再可用。

事件:'aborted'#

'aborted' 事件在 Http2Stream 例項在通訊中途被異常中止時觸發。其監聽器不接收任何引數。

'aborted' 事件僅在 Http2Stream 可寫端尚未結束時觸發。

事件:'close'#

'close' 事件在 Http2Stream 被銷燬時觸發。一旦此事件觸發,Http2Stream 例項將不再可用。

關閉流時使用的 HTTP/2 錯誤碼可以透過 http2stream.rstCode 屬性獲取。如果程式碼是除 NGHTTP2_NO_ERROR (0) 之外的任何值,則也已觸發了 'error' 事件。

事件:'error'#

'error' 事件在處理 Http2Stream 期間發生錯誤時觸發。

事件:'frameError'#

'frameError' 事件在嘗試傳送幀時發生錯誤時觸發。呼叫時,處理函式將接收一個標識幀型別的整數引數和一個標識錯誤碼的整數引數。Http2Stream 例項將在 'frameError' 事件觸發後立即銷燬。

事件:'ready'#

'ready' 事件在 Http2Stream 已開啟、已分配 id 並可使用時觸發。監聽器不接收任何引數。

事件:'timeout'#

在使用 http2stream.setTimeout() 設定的毫秒數內,如果此 Http2Stream 未收到任何活動,則會觸發 'timeout' 事件。其監聽器不接收任何引數。

事件:'trailers'#

'trailers' 事件在接收到與尾部頭欄位關聯的頭塊時觸發。監聽器回撥函式將接收到 HTTP/2 Headers 物件和與頭關聯的標誌。

如果在接收到尾部資料之前呼叫了 http2stream.end(),並且沒有讀取或監聽傳入的資料,則可能不會觸發此事件。

stream.on('trailers', (headers, flags) => {
  console.log(headers);
}); 
事件:'wantTrailers'#

Http2Stream 已將最後一個 DATA 幀排隊傳送,並且 Http2Stream 準備好傳送尾部頭時,會觸發 'wantTrailers' 事件。在發起請求或響應時,必須設定 waitForTrailers 選項才能觸發此事件。

http2stream.aborted#

如果 Http2Stream 例項被異常中止,則設定為 true。設定後,將觸發 'aborted' 事件。

http2stream.bufferSize#

此屬性顯示當前已緩衝待寫入的字元數。詳情請參見 net.Socket.bufferSize

http2stream.close(code[, callback])#
  • code <number> 標識錯誤碼的無符號 32 位整數。預設值:http2.constants.NGHTTP2_NO_ERROR (0x00)。
  • callback <Function> 一個可選的函式,註冊用於監聽 'close' 事件。

透過向連線的 HTTP/2 對等端傳送一個 RST_STREAM 幀來關閉 Http2Stream 例項。

http2stream.closed#

如果 Http2Stream 例項已關閉,則設定為 true

http2stream.destroyed#

如果 Http2Stream 例項已被銷燬且不再可用,則設定為 true

http2stream.endAfterHeaders#

如果接收到的請求或響應 HEADERS 幀中設定了 END_STREAM 標誌,則設定為 true,表示不應再接收額外資料,並且 Http2Stream 的可讀端將被關閉。

http2stream.id#

Http2Stream 例項的數字流識別符號。如果尚未分配流識別符號,則設定為 undefined

http2stream.pending#

如果 Http2Stream 例項尚未被分配數字流識別符號,則設定為 true

http2stream.priority(options)#

穩定性:0 - 已棄用:RFC 9113 已棄用優先順序信令的支援,Node.js 不再支援。

空方法,僅為保持部分向後相容性而存在。

http2stream.rstCode#

Http2Stream 在接收到來自連線對等端的 RST_STREAM 幀、呼叫 http2stream.close()http2stream.destroy() 後被銷燬時,設定為報告的 RST_STREAM 錯誤碼。如果 Http2Stream 尚未關閉,則為 undefined

http2stream.sentHeaders#

一個包含為此 Http2Stream 傳送的出站頭部的物件。

http2stream.sentInfoHeaders#

一個物件陣列,包含為此 Http2Stream 傳送的出站資訊(附加)頭部。

http2stream.sentTrailers#

一個包含為此 HttpStream 傳送的出站尾部的物件。

http2stream.session#

對此 Http2Stream 所屬的 Http2Session 例項的引用。在 Http2Stream 例項被銷燬後,該值將為 undefined

http2stream.setTimeout(msecs, callback)#
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)#

向連線的 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#

ClientHttp2Stream 類是 Http2Stream 的擴充套件,專門用於 HTTP/2 客戶端。客戶端上的 Http2Stream 例項提供諸如 'response''push' 等僅與客戶端相關的事件。

事件:'continue'#

當伺服器傳送 100 Continue 狀態時觸發,通常是因為請求包含了 Expect: 100-continue。這是一個指示客戶端應該傳送請求體的指令。

事件:'headers'#

'headers' 事件在接收到流的附加頭塊時觸發,例如當接收到 1xx 資訊頭塊時。監聽器回撥函式會接收到 HTTP/2 Headers 物件、與頭關聯的標誌以及原始格式的頭(參見 HTTP/2 原始 Headers)。

stream.on('headers', (headers, flags) => {
  console.log(headers);
}); 
事件:'push'#

'push' 事件在接收到伺服器推送流的響應頭時觸發。監聽器回撥函式會接收到 HTTP/2 Headers 物件和與頭關聯的標誌。

stream.on('push', (headers, flags) => {
  console.log(headers);
}); 
事件:'response'#

'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#

ServerHttp2Stream 類是 Http2Stream 的擴充套件,專門用於 HTTP/2 伺服器。伺服器上的 Http2Stream 例項提供了諸如 http2stream.pushStream()http2stream.respond() 等僅與伺服器相關的方法。

http2stream.additionalHeaders(headers)#

向連線的 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 Headers Object>
  • options <Object>
    • exclusive <boolean> 當為 trueparent 標識了一個父流時,建立的流將成為父流的唯一直接依賴項,所有其他現有依賴項都將成為新建立流的依賴項。預設值:false
    • parent <number> 指定新建立流所依賴的流的數字識別符號。
  • callback <Function> 推送流啟動後呼叫的回撥函式。

啟動一個推送流。回撥函式被呼叫時,會將為推送流建立的新的 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]])#
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]])#

啟動一個響應,其資料從給定的檔案描述符中讀取。不對給定的檔案描述符進行驗證。如果在嘗試使用檔案描述符讀取資料時發生錯誤,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() 呼叫以收集有關所提供檔案描述符的詳細資訊。

offsetlength 選項可用於將響應限制為特定的範圍子集。例如,這可以用於支援 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 必須指定一個常規檔案,否則將在 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 頭欄位將被自動設定。

offsetlength 選項可用於將響應限制為特定的範圍子集。例如,這可以用於支援 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#

Http2Server 的例項是使用 http2.createServer() 函式建立的。Http2Server 類不由 node:http2 模組直接匯出。

事件:'checkContinue'#

如果註冊了 'request' 監聽器或 http2.createServer() 提供了一個回撥函式,那麼每次收到帶有 HTTP Expect: 100-continue 的請求時,都會觸發 'checkContinue' 事件。如果沒有監聽此事件,伺服器將自動響應一個 100 Continue 狀態(如果適用)。

處理此事件需要呼叫 response.writeContinue()(如果客戶端應繼續傳送請求體),或生成一個適當的 HTTP 響應(例如 400 Bad Request)(如果客戶端不應繼續傳送請求體)。

當此事件被觸發並處理時,'request' 事件將不會被觸發。

事件:'connection'#

當建立新的 TCP 流時會觸發此事件。socket 通常是 net.Socket 型別的物件。使用者通常不需要訪問此事件。

使用者也可以顯式地觸發此事件,以將連線注入到 HTTP 伺服器中。在這種情況下,可以傳遞任何 Duplex 流。

事件:'request'#

每次有請求時都會觸發。每個會話可能會有多個請求。請參閱相容性 API

事件:'session'#

Http2Server 建立新的 Http2Session 時,會觸發 'session' 事件。

事件:'sessionError'#

當與 Http2Server 關聯的 Http2Session 物件觸發 'error' 事件時,會觸發 'sessionError' 事件。

事件:'stream'#

當與伺服器關聯的 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])#

阻止伺服器建立新的會話。由於 HTTP/2 會話的永續性,這不會阻止建立新的請求流。要優雅地關閉伺服器,請在所有活動會話上呼叫 http2session.close()

如果提供了 callback,它將在所有活動會話關閉後才被呼叫,儘管伺服器已經停止接受新會話。更多詳情請參閱 net.Server.close()

server[Symbol.asyncDispose]()#

呼叫 server.close() 並返回一個 Promise,該 Promise 在伺服器關閉時兌現。

server.setTimeout([msecs][, callback])#

用於設定 http2 伺服器請求的超時值,並設定一個回撥函式,當 Http2Servermsecs 毫秒後沒有任何活動時呼叫該函式。

給定的回撥函式會作為監聽器註冊到 'timeout' 事件上。

如果 callback 不是一個函式,將會丟擲一個新的 ERR_INVALID_ARG_TYPE 錯誤。

server.timeout#
  • 型別:<number> 超時時間(毫秒)。預設值:0(無超時)

套接字被假定為超時前的不活動毫秒數。

0 將停用傳入連線的超時行為。

套接字超時邏輯在連線時設定,因此更改此值僅影響到伺服器的新連線,不影響任何現有連線。

server.updateSettings([settings])#

用於使用提供的設定更新伺服器。

對於無效的 settings 值,會丟擲 ERR_HTTP2_INVALID_SETTING_VALUE

對於無效的 settings 引數,會丟擲 ERR_INVALID_ARG_TYPE

類:Http2SecureServer#

Http2SecureServer 的例項是使用 http2.createSecureServer() 函式建立的。Http2SecureServer 類不由 node:http2 模組直接匯出。

事件:'checkContinue'#

如果註冊了 'request' 監聽器,或者 http2.createSecureServer() 提供了一個回撥函式,那麼每當收到帶有 HTTP Expect: 100-continue 的請求時,就會觸發 'checkContinue' 事件。如果沒有監聽此事件,伺服器將自動酌情響應狀態碼 100 Continue

處理此事件需要呼叫 response.writeContinue()(如果客戶端應繼續傳送請求體),或生成一個適當的 HTTP 響應(例如 400 Bad Request)(如果客戶端不應繼續傳送請求體)。

當此事件被觸發並處理時,'request' 事件將不會被觸發。

事件:'connection'#

在 TLS 握手開始之前,當建立新的 TCP 流時,會觸發此事件。socket 通常是 net.Socket 型別的物件。使用者通常不需要訪問此事件。

使用者也可以顯式地觸發此事件,以將連線注入到 HTTP 伺服器中。在這種情況下,可以傳遞任何 Duplex 流。

事件:'request'#

每次有請求時都會觸發。每個會話可能會有多個請求。請參閱相容性 API

事件:'session'#

Http2SecureServer 建立新的 Http2Session 時,會觸發 'session' 事件。

事件:'sessionError'#

當與 Http2SecureServer 關聯的 Http2Session 物件觸發 'error' 事件時,會觸發 'sessionError' 事件。

事件:'stream'#

當與伺服器關聯的 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'#

當連線的客戶端未能協商一個允許的協議(即 HTTP/2 或 HTTP/1.1)時,會觸發 'unknownProtocol' 事件。事件處理程式會接收到用於處理的套接字。如果沒有為此事件註冊監聽器,連線將被終止。可以使用傳遞給 http2.createSecureServer()'unknownProtocolTimeout' 選項指定超時時間。

在早期版本的 Node.js 中,如果 allowHTTP1false,並且在 TLS 握手期間,客戶端既沒有傳送 ALPN 擴充套件,也沒有傳送不包含 HTTP/2 (h2) 的 ALPN 擴充套件,則會觸發此事件。較新版本的 Node.js 僅在 allowHTTP1false 且客戶端未傳送 ALPN 擴充套件時才觸發此事件。如果客戶端傳送的 ALPN 擴充套件不包含 HTTP/2(或在 allowHTTP1true 時不包含 HTTP/1.1),TLS 握手將失敗,並且不會建立安全連線。

請參閱相容性 API

server.close([callback])#

阻止伺服器建立新的會話。由於 HTTP/2 會話的永續性,這不會阻止建立新的請求流。要優雅地關閉伺服器,請在所有活動會話上呼叫 http2session.close()

如果提供了 callback,它將在所有活動會話關閉後才被呼叫,儘管伺服器已經停止接受新會話。更多詳情請參閱 tls.Server.close()

server.setTimeout([msecs][, callback])#

用於設定 http2 安全伺服器請求的超時值,並設定一個回撥函式,當 Http2SecureServermsecs 毫秒後沒有任何活動時呼叫該函式。

給定的回撥函式會作為監聽器註冊到 'timeout' 事件上。

如果 callback 不是一個函式,將會丟擲一個新的 ERR_INVALID_ARG_TYPE 錯誤。

server.timeout#
  • 型別:<number> 超時時間(毫秒)。預設值:0(無超時)

套接字被假定為超時前的不活動毫秒數。

0 將停用傳入連線的超時行為。

套接字超時邏輯在連線時設定,因此更改此值僅影響到伺服器的新連線,不影響任何現有連線。

server.updateSettings([settings])#

用於使用提供的設定更新伺服器。

對於無效的 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 會話的數量、標頭壓縮表的當前記憶體使用量、排隊等待發送的當前資料以及未確認的 PINGSETTINGS 幀都計入當前限制。預設值:10
    • maxHeaderListPairs <number> 設定標頭條目的最大數量。這類似於 node:http 模組中的 server.maxHeadersCountrequest.maxHeadersCount。最小值為 4預設值:128
    • maxOutstandingPings <number> 設定未完成、未確認的 ping 的最大數量。預設值:10
    • maxSendHeaderBlockLength <number> 設定序列化、壓縮的標頭塊的最大允許大小。嘗試傳送超過此限制的標頭將導致觸發 'frameError' 事件,並且流將被關閉和銷燬。雖然這為整個標頭塊設定了最大允許大小,但 nghttp2(內部 http2 庫)對每個解壓縮的鍵/值對有 65536 的限制。
    • paddingStrategy <number> 用於確定 HEADERSDATA 幀使用的填充量的策略。預設值: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 會話的數量、標頭壓縮表的當前記憶體使用量、排隊等待發送的當前資料以及未確認的 PINGSETTINGS 幀都計入當前限制。預設值:10
    • maxHeaderListPairs <number> 設定標頭條目的最大數量。這類似於 node:http 模組中的 server.maxHeadersCountrequest.maxHeadersCount。最小值為 4預設值:128
    • maxOutstandingPings <number> 設定未完成、未確認的 ping 的最大數量。預設值:10
    • maxSendHeaderBlockLength <number> 設定序列化、壓縮的標頭塊的最大允許大小。嘗試傳送超過此限制的標頭將導致觸發 'frameError' 事件,並且流將被關閉和銷燬。
    • paddingStrategy <number> 用於確定 HEADERSDATA 幀使用的填充量的策略。預設值: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() 選項。對於伺服器,通常需要身份選項(pfxkey/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 會話的數量、標頭壓縮表的當前記憶體使用量、排隊等待發送的當前資料以及未確認的 PINGSETTINGS 幀都計入當前限制。預設值:10
    • maxHeaderListPairs <number> 設定標頭條目的最大數量。這類似於 node:http 模組中的 server.maxHeadersCountrequest.maxHeadersCount。最小值為 1預設值:128
    • maxOutstandingPings <number> 設定未完成、未確認的 ping 的最大數量。預設值:10
    • maxReservedRemoteStreams <number> 設定客戶端在任何給定時間將接受的保留推送流的最大數量。一旦當前保留的推送流數量達到此限制,伺服器傳送的新推送流將被自動拒絕。允許的最小值為 0。允許的最大值為 232-1。負值將此選項設定為最大允許值。預設值:200
    • maxSendHeaderBlockLength <number> 設定序列化、壓縮的標頭塊的最大允許大小。嘗試傳送超過此限制的標頭將導致觸發 'frameError' 事件,並且流將被關閉和銷燬。
    • paddingStrategy <number> 用於確定 HEADERSDATA 幀使用的填充量的策略。預設值: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> 一個可選的回撥函式,接收傳遞給 connectURL 例項和 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_STREAMGOAWAY 的錯誤程式碼#
名稱常量
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.1http2.constants.NGHTTP2_HTTP_1_1_REQUIRED

當伺服器在透過 http2server.setTimeout() 設定的給定毫秒數內沒有任何活動時,會觸發 'timeout' 事件。

http2.getDefaultSettings()#

返回一個包含 Http2Session 例項預設設定的物件。此方法每次呼叫時都會返回一個新的物件例項,因此返回的例項可以安全地修改使用。

http2.getPackedSettings([settings])#

返回一個 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)#

返回一個 HTTP/2 設定物件,其中包含從給定 Buffer 反序列化的設定,該 Bufferhttp2.getPackedSettings() 生成。

http2.performServerHandshake(socket[, options])#

從現有套接字建立 HTTP/2 伺服器會話。

http2.sensitiveHeaders#

此符號可以作為屬性設定在 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:protocolageauthorizationaccess-control-allow-credentialsaccess-control-max-ageaccess-control-request-methodcontent-encodingcontent-languagecontent-lengthcontent-locationcontent-md5content-rangecontent-typedatedntetagexpiresfromhostif-matchif-modified-sinceif-none-matchif-rangeif-unmodified-sincelast-modifiedlocationmax-forwardsproxy-authorizationrangerefererretry-aftertkupgrade-insecure-requestsuser-agentx-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 標頭壓縮演算法永遠不會對它們進行索引。這對於熵較低且可能被攻擊者認為有價值的標頭值(例如 CookieAuthorization)是有意義的。要實現這一點,請將標頭名稱新增到 [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.localSettingshttp2session.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 報告。

當在不正確的時間嘗試執行某個操作時(例如,在流關閉後嘗試在其上傳送資料),會發生狀態錯誤。這些錯誤將透過同步的 throwHttp2StreamHttp2Session 或 HTTP/2 伺服器物件上的 'error' 事件報告,具體取決於錯誤發生的位置和時間。

當 HTTP/2 會話意外失敗時,會發生內部錯誤。這些錯誤將透過 Http2Session 或 HTTP/2 伺服器物件上的 'error' 事件報告。

當違反各種 HTTP/2 協議約束時,會發生協議錯誤。這些錯誤將透過同步的 throwHttp2StreamHttp2Session 或 HTTP/2 伺服器物件上的 'error' 事件報告,具體取決於錯誤發生的位置和時間。

標頭名稱和值中的無效字元處理#

HTTP/2 實現對 HTTP 標頭名稱和值中的無效字元的處理比 HTTP/1 實現更嚴格。

標頭欄位名稱*不區分大小寫*,並在網路上傳輸時嚴格作為小寫字串。Node.js 提供的 API 允許將標頭名稱設定為混合大小寫字串(例如 Content-Type),但在傳輸時會將其轉換為小寫(例如 content-type)。

標頭欄位名稱*必須僅*包含以下一個或多個 ASCII 字元:a-zA-Z0-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 由 Http2ServerRequestHttp2ServerResponse 組成。它們旨在與 HTTP/1 的 API 相容,但它們不隱藏協議之間的差異。例如,HTTP 狀態碼的狀態訊息被忽略。

ALPN 協商#

ALPN 協商允許在同一個套接字上同時支援 HTTPS 和 HTTP/2。reqres 物件可以是 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#

Http2ServerRequest 物件由 http2.Serverhttp2.SecureServer 建立,並作為第一個引數傳遞給 'request' 事件。它可用於訪問請求狀態、標頭和資料。

事件:'aborted'#

每當 Http2ServerRequest 例項在通訊中途異常中止時,就會觸發 'aborted' 事件。

只有在 Http2ServerRequest 的可寫端尚未結束時,才會觸發 'aborted' 事件。

事件:'close'#

表示底層的 Http2Stream 已關閉。與 'end' 一樣,此事件每個響應只發生一次。

request.aborted#

如果請求已被中止,request.aborted 屬性將為 true

request.authority#

請求的 authority 偽標頭欄位。因為 HTTP/2 允許請求設定 :authorityhost,所以如果存在 req.headers[':authority'],則此值派生自它。否則,它派生自 req.headers['host']

request.complete#

如果請求已完成、中止或銷燬,request.complete 屬性將為 true

request.connection#

穩定性:0 - 已棄用。請使用 request.socket

請參閱 request.socket

request.destroy([error])#

在接收到 Http2ServerRequestHttp2Stream 上呼叫 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#

請求的 scheme 偽標頭欄位,指示目標 URL 的方案部分。

request.setTimeout(msecs, callback)#

Http2Stream 的超時值設定為 msecs。如果提供了回撥,則將其新增為響應物件上 'timeout' 事件的監聽器。

如果沒有為請求、響應或伺服器新增 'timeout' 監聽器,那麼當 Http2Stream 超時時,它們將被銷燬。如果為請求、響應或伺服器的 'timeout' 事件分配了處理程式,則必須顯式處理超時的套接字。

request.socket#

返回一個充當 net.Socket(或 tls.TLSSocket)的 Proxy 物件,但會根據 HTTP/2 邏輯應用 getter、setter 和方法。

destroyedreadablewritable 屬性將從 request.stream 中檢索和設定。

destroyemitendononce 方法將在 request.stream 上呼叫。

setTimeout 方法將在 request.stream.session 上呼叫。

pausereadresumewrite 將丟擲一個帶有程式碼 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'#

表示底層的 Http2Streamresponse.end() 被呼叫或能夠重新整理之前已終止。

事件:'finish'#

當響應已傳送時觸發。更具體地說,此事件在響應標頭和正文的最後一部分已移交給 HTTP/2 多路複用以透過網路傳輸時觸發。這並不意味著客戶端已經收到了任何東西。

在此事件之後,響應物件上將不再觸發任何事件。

response.addTrailers(headers)#

此方法向響應新增 HTTP 尾部標頭(位於訊息末尾的標頭)。

嘗試設定包含無效字元的標頭欄位名稱或值將導致丟擲 TypeError

response.appendHeader(name, value)#

向標頭物件追加單個標頭值。

如果值是陣列,這等同於多次呼叫此方法。

如果該標頭之前沒有值,這等同於呼叫 response.setHeader()

嘗試設定包含無效字元的標頭欄位名稱或值將導致丟擲 TypeError

// Returns headers including "set-cookie: a" and "set-cookie: b"
const server = http2.createServer((req, res) => {
  res.setHeader('set-cookie', 'a');
  res.appendHeader('set-cookie', 'b');
  res.writeHead(200);
  res.end('ok');
}); 
response.connection#

穩定性:0 - 已棄用。請使用 response.socket

請參閱 response.socket

response.createPushResponse(headers, callback)#
  • headers <HTTP/2 Headers Object> 描述 Headers 的物件
  • callback <Function>http2stream.pushStream() 完成後呼叫一次,或者在嘗試建立推送的 Http2Stream 失敗或被拒絕時,或者在呼叫 http2stream.pushStream() 方法之前 Http2ServerRequest 的狀態已關閉時呼叫

使用給定的標頭呼叫 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#

穩定性:0 - 已棄用。請使用 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)#

刪除已排隊等待隱式傳送的標頭。

response.removeHeader('Content-Encoding'); 
response.req#

對原始 HTTP2 request 物件的引用。

response.sendDate#

當為 true 時,如果 Date 標頭尚未出現在標頭中,則會自動生成併發送在響應中。預設為 true。

這隻應在測試時停用;HTTP 要求響應中包含 Date 標頭。

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])#

Http2Stream 的超時值設定為 msecs。如果提供了回撥,則將其新增為響應物件上 'timeout' 事件的監聽器。

如果沒有為請求、響應或伺服器新增 'timeout' 監聽器,那麼當 Http2Stream 超時時,它們將被銷燬。如果為請求、響應或伺服器的 'timeout' 事件分配了處理程式,則必須顯式處理超時的套接字。

response.socket#

返回一個充當 net.Socket(或 tls.TLSSocket)的 Proxy 物件,但會根據 HTTP/2 邏輯應用 getter、setter 和方法。

destroyedreadablewritable 屬性將從 response.stream 中檢索和設定。

destroyemitendononce 方法將在 response.stream 上呼叫。

setTimeout 方法將在 response.stream.session 上呼叫。

pausereadresumewrite 將丟擲一個帶有程式碼 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#

當使用隱式標頭時(不顯式呼叫 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 請求時,會省略響應正文。類似地,204304 響應*不得*包含訊息體。

chunk 可以是字串或緩衝區。如果 chunk 是字串,第二個引數指定如何將其編碼為位元組流。預設情況下,encoding'utf8'。當此資料塊被重新整理時,將呼叫 callback

這是原始的 HTTP 正文,與可能使用的更高級別的多部分正文編碼無關。

第一次呼叫 response.write() 時,它將把緩衝的標頭資訊和正文的第一個塊傳送給客戶端。第二次呼叫 response.write() 時,Node.js 假定資料將以流式傳輸,並單獨傳送新資料。也就是說,響應被緩衝到正文的第一個塊。

如果所有資料都成功重新整理到核心緩衝區,則返回 true。如果全部或部分資料被排隊在使用者記憶體中,則返回 false。當緩衝區再次空閒時,將觸發 'drain' 事件。

response.writeContinue()#

向客戶端傳送狀態碼 100 Continue,表示應傳送請求正文。請參閱 Http2ServerHttp2SecureServer 上的 'checkContinue' 事件。

response.writeEarlyHints(hints)#

向客戶端傳送狀態碼 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])#

向請求傳送響應標頭。狀態碼是一個 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 來收集每個 Http2SessionHttp2Stream 例項的基本效能指標。

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'] });

PerformanceEntryentryType 屬性將等於 'http2'

PerformanceEntryname 屬性將等於 'Http2Stream''Http2Session'

如果 name 等於 Http2StreamPerformanceEntry 將包含以下附加屬性

  • 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 等於 Http2SessionPerformanceEntry 將包含以下附加屬性

  • 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 的型別。

關於 :authorityhost 的說明#

HTTP/2 要求請求必須有 :authority 偽標頭或 host 標頭。直接構建 HTTP/2 請求時優先使用 :authority,從 HTTP/1 轉換時(例如在代理中)優先使用 host

如果 :authority 不存在,相容性 API 會回退到 host。更多資訊請參閱 request.authority。但是,如果您不使用相容性 API(或直接使用 req.headers),則需要自己實現任何回退行為。