Node.js v26.0.0 說明文件
- Node.js v26.0.0
- 目錄
- 索引
- 關於此說明文件
- 用法與範例
- 斷言測試
- 非同步內容追蹤
- Async hooks
- Buffer
- C++ 擴充套件
- 使用 Node-API 的 C/C++ 擴充套件
- C++ 嵌入器 API
- 子程序
- 叢集
- 命令列選項
- Console
- Crypto
- 除錯器
- 棄用的 API
- Diagnostics Channel
- DNS
- 網域 (Domain)
- 環境變數
- 錯誤
- 事件
- 檔案系統
- 全域變數
- HTTP
- HTTP/2
- HTTPS
- 檢查器
- 國際化
- 模組:CommonJS 模組
- 模組:ECMAScript 模組
- 模組:
node:moduleAPI - 模組:套件
- 模組:TypeScript
- Net
- Iterable Streams API
- OS
- Path
- 效能勾子 (Performance hooks)
- 權限
- 程序
- Punycode
- 查詢字串
- Readline
- REPL
- 報告
- 單一可執行應用程式
- SQLite
- Stream
- 字串解碼器
- 測試執行器
- 計時器
- TLS/SSL
- 追蹤事件
- TTY
- UDP/資料報
- URL
- 公用工具
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- 工作執行緒
- Zlib
- Zlib 可反覆運算壓縮
- 其他版本
- 選項
HTTPS#
穩定度:2 - 穩定
HTTPS 是基於 TLS/SSL 的 HTTP 協定。在 Node.js 中,它是作為一個獨立的模組來實作的。
判斷是否不支援加密 (crypto)#
Node.js 有可能在編譯時未包含對 node:crypto 模組的支援。在這種情況下,嘗試從 https 進行 import 或呼叫 require('node:https') 將會拋出錯誤。
使用 CommonJS 時,拋出的錯誤可以使用 try/catch 來捕捉
let https;
try {
https = require('node:https');
} catch (err) {
console.error('https support is disabled!');
}
使用詞法 ESM import 關鍵字時,只有在嘗試載入模組之前已註冊了 process.on('uncaughtException') 的處理常式(例如,使用預載入模組),才能捕捉到該錯誤。
使用 ESM 時,如果程式碼有可能在未啟用加密支援的 Node.js 版本上執行,請考慮使用 import() 函數,而不是詞法 import 關鍵字
let https;
try {
https = await import('node:https');
} catch (err) {
console.error('https support is disabled!');
}
類別:https.Agent#
一個用於 HTTPS 的 Agent 物件,類似於 http.Agent。更多資訊請參閱 https.request()。
與 http.Agent 一樣,可以覆寫 createConnection(options[, callback]) 方法來自訂如何建立 TLS 連線。
關於覆寫此方法的詳細資訊,包括使用回呼(callback)進行非同步 Socket 建立,請參閱
agent.createConnection()。
new Agent([options])#
options<Object>可在代理程式(agent)上設定的一組可配置選項。可以具有與http.Agent(options)相同的欄位,以及:-
maxCachedSessions<number>TLS 快取連線階段的最大數量。使用0可停用 TLS 連線階段快取。預設值:100。 -
servername<string>要傳送給伺服器的 伺服器名稱指示(Server Name Indication)延伸模組 的值。使用空字串''可停用傳送該延伸模組。預設值:目標伺服器的主機名稱,除非目標伺服器是使用 IP 位址指定,在該情況下預設值為''(無延伸模組)。有關 TLS 連線階段重用的資訊,請參閱
連線階段恢復(Session Resumption)。
-
事件:'keylog'#
line<Buffer>一行 ASCII 文字,格式為 NSSSSLKEYLOGFILE格式。tlsSocket<tls.TLSSocket>產生該事件的tls.TLSSocket實例。
當此代理程式管理的連線產生或接收到金鑰材料時(通常是在交握完成之前,但不一定),會觸發 keylog 事件。這些金鑰材料可以儲存以供除錯使用,因為它允許對擷取的 TLS 流量進行解密。對於每個 socket,它可能會被觸發多次。
一個典型的用例是將接收到的行附加到一個共用的文字檔中,該檔案隨後被軟體(如 Wireshark)用來解密流量。
// ...
https.globalAgent.on('keylog', (line, tlsSocket) => {
fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 });
});
類別:https.Server#
- 繼承:
<tls.Server>
更多資訊請參閱 http.Server。
server.close([callback])#
callback<Function>- 回傳值:
<https.Server>
請參閱 node:http 模組中的 server.close()。
server[Symbol.asyncDispose]()#
呼叫 server.close() 並傳回一個在伺服器關閉時實現(fulfill)的 Promise。
server.closeAllConnections()#
請參閱 node:http 模組中的 server.closeAllConnections()。
server.closeIdleConnections()#
請參閱 node:http 模組中的 server.closeIdleConnections()。
server.headersTimeout#
- 類型:
<number>預設值:60000
請參閱 node:http 模組中的 server.headersTimeout。
server.listen()#
啟動 HTTPS 伺服器以監聽加密連線。此方法與 net.Server 中的 server.listen() 完全相同。
server.maxHeadersCount#
- 類型:
<number>預設值:2000
請參閱 node:http 模組中的 server.maxHeadersCount。
server.requestTimeout#
- 類型:
<number>預設值:300000
請參閱 node:http 模組中的 server.requestTimeout。
server.setTimeout([msecs][, callback])#
msecs<number>預設值:120000(2 分鐘)callback<Function>- 回傳值:
<https.Server>
請參閱 node:http 模組中的 server.setTimeout()。
server.timeout#
- 類型:
<number>預設值: 0 (無逾時)
請參閱 node:http 模組中的 server.timeout。
server.keepAliveTimeout#
- 類型:
<number>預設值:5000(5 秒)
請參閱 node:http 模組中的 server.keepAliveTimeout。
https.createServer([options][, requestListener])#
options<Object>接受來自tls.createServer()、tls.createSecureContext()以及http.createServer()的options。requestListener<Function>要新增至'request'事件的監聽器。- 回傳值:
<https.Server>
// curl -k https://:8000/ import { createServer } from 'node:https'; import { readFileSync } from 'node:fs'; const options = { key: readFileSync('private-key.pem'), cert: readFileSync('certificate.pem'), }; createServer(options, (req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000);// curl -k https://:8000/ const https = require('node:https'); const fs = require('node:fs'); const options = { key: fs.readFileSync('private-key.pem'), cert: fs.readFileSync('certificate.pem'), }; https.createServer(options, (req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000);
或
import { createServer } from 'node:https'; import { readFileSync } from 'node:fs'; const options = { pfx: readFileSync('test_cert.pfx'), passphrase: 'sample', }; createServer(options, (req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000);const https = require('node:https'); const fs = require('node:fs'); const options = { pfx: fs.readFileSync('test_cert.pfx'), passphrase: 'sample', }; https.createServer(options, (req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000);
若要產生此範例的憑證與金鑰,請執行
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
-keyout private-key.pem -out certificate.pem
接著,要為此範例產生 pfx 憑證,請執行
openssl pkcs12 -certpbe AES-256-CBC -export -out test_cert.pfx \
-inkey private-key.pem -in certificate.pem -passout pass:sample
https.get(options[, callback])#
https.get(url[, options][, callback])#
url<string>|<URL>options<Object>|<string>|<URL>接受與https.request()相同的options,且方法預設設為 GET。callback<Function>- 回傳:
<http.ClientRequest>
類似 http.get(),但用於 HTTPS。
options 可以是物件、字串或 URL 物件。若 options 是字串,它會自動使用 new URL() 進行解析。若它是 URL 物件,它將自動轉換為普通的 options 物件。
import { get } from 'node:https'; import process from 'node:process'; get('https://encrypted.google.com/', (res) => { console.log('statusCode:', res.statusCode); console.log('headers:', res.headers); res.on('data', (d) => { process.stdout.write(d); }); }).on('error', (e) => { console.error(e); });const https = require('node:https'); https.get('https://encrypted.google.com/', (res) => { console.log('statusCode:', res.statusCode); console.log('headers:', res.headers); res.on('data', (d) => { process.stdout.write(d); }); }).on('error', (e) => { console.error(e); });
https.globalAgent#
用於所有 HTTPS 客戶端請求的 https.Agent 全域實例。與預設的 https.Agent 設定不同之處在於,它啟用了 keepAlive 並有 5 秒的 timeout。
https.request(options[, callback])#
https.request(url[, options][, callback])#
url<string>|<URL>options<Object>|<string>|<URL>接受來自http.request()的所有options,但預設值有一些差異:protocol預設值:'https:'port預設值:443agent預設值:https.globalAgent
callback<Function>- 回傳:
<http.ClientRequest>
向安全的 Web 伺服器發出請求。
同時也接受來自 tls.connect() 的以下額外 options:ca、cert、ciphers、clientCertEngine (已棄用)、crl、dhparam、ecdhCurve、honorCipherOrder、key、passphrase、pfx、rejectUnauthorized、secureOptions、secureProtocol、servername、sessionIdContext、highWaterMark。
options 可以是物件、字串或 URL 物件。若 options 是字串,它會自動使用 new URL() 進行解析。若它是 URL 物件,它將自動轉換為普通的 options 物件。
https.request() 回傳 http.ClientRequest 類別的實例。ClientRequest 實例是一個可寫入串流(writable stream)。若需要使用 POST 請求上傳檔案,則寫入 ClientRequest 物件。
import { request } from 'node:https'; import process from 'node:process'; const options = { hostname: 'encrypted.google.com', port: 443, path: '/', method: 'GET', }; const req = request(options, (res) => { console.log('statusCode:', res.statusCode); console.log('headers:', res.headers); res.on('data', (d) => { process.stdout.write(d); }); }); req.on('error', (e) => { console.error(e); }); req.end();const https = require('node:https'); const options = { hostname: 'encrypted.google.com', port: 443, path: '/', method: 'GET', }; const req = https.request(options, (res) => { console.log('statusCode:', res.statusCode); console.log('headers:', res.headers); res.on('data', (d) => { process.stdout.write(d); }); }); req.on('error', (e) => { console.error(e); }); req.end();
使用來自 tls.connect() 的選項範例:
const options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
key: fs.readFileSync('private-key.pem'),
cert: fs.readFileSync('certificate.pem'),
};
options.agent = new https.Agent(options);
const req = https.request(options, (res) => {
// ...
});
或者,透過不使用 Agent 來選擇不使用連線池(connection pooling)。
const options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
key: fs.readFileSync('private-key.pem'),
cert: fs.readFileSync('certificate.pem'),
agent: false,
};
const req = https.request(options, (res) => {
// ...
});
使用 URL 作為 options 的範例
const options = new URL('https://abc:xyz@example.com');
const req = https.request(options, (res) => {
// ...
});
關於憑證指紋或公開金鑰的固定(pinning)範例(類似 pin-sha256):
import { checkServerIdentity } from 'node:tls'; import { Agent, request } from 'node:https'; import { createHash } from 'node:crypto'; function sha256(s) { return createHash('sha256').update(s).digest('base64'); } const options = { hostname: 'github.com', port: 443, path: '/', method: 'GET', checkServerIdentity: function(host, cert) { // Make sure the certificate is issued to the host we are connected to const err = checkServerIdentity(host, cert); if (err) { return err; } // Pin the public key, similar to HPKP pin-sha256 pinning const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='; if (sha256(cert.pubkey) !== pubkey256) { const msg = 'Certificate verification error: ' + `The public key of '${cert.subject.CN}' ` + 'does not match our pinned fingerprint'; return new Error(msg); } // Pin the exact certificate, rather than the pub key const cert256 = 'FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' + '0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65'; if (cert.fingerprint256 !== cert256) { const msg = 'Certificate verification error: ' + `The certificate of '${cert.subject.CN}' ` + 'does not match our pinned fingerprint'; return new Error(msg); } // This loop is informational only. // Print the certificate and public key fingerprints of all certs in the // chain. Its common to pin the public key of the issuer on the public // internet, while pinning the public key of the service in sensitive // environments. let lastprint256; do { console.log('Subject Common Name:', cert.subject.CN); console.log(' Certificate SHA256 fingerprint:', cert.fingerprint256); const hash = createHash('sha256'); console.log(' Public key ping-sha256:', sha256(cert.pubkey)); lastprint256 = cert.fingerprint256; cert = cert.issuerCertificate; } while (cert.fingerprint256 !== lastprint256); }, }; options.agent = new Agent(options); const req = request(options, (res) => { console.log('All OK. Server matched our pinned cert or public key'); console.log('statusCode:', res.statusCode); res.on('data', (d) => {}); }); req.on('error', (e) => { console.error(e.message); }); req.end();const tls = require('node:tls'); const https = require('node:https'); const crypto = require('node:crypto'); function sha256(s) { return crypto.createHash('sha256').update(s).digest('base64'); } const options = { hostname: 'github.com', port: 443, path: '/', method: 'GET', checkServerIdentity: function(host, cert) { // Make sure the certificate is issued to the host we are connected to const err = tls.checkServerIdentity(host, cert); if (err) { return err; } // Pin the public key, similar to HPKP pin-sha256 pinning const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='; if (sha256(cert.pubkey) !== pubkey256) { const msg = 'Certificate verification error: ' + `The public key of '${cert.subject.CN}' ` + 'does not match our pinned fingerprint'; return new Error(msg); } // Pin the exact certificate, rather than the pub key const cert256 = 'FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' + '0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65'; if (cert.fingerprint256 !== cert256) { const msg = 'Certificate verification error: ' + `The certificate of '${cert.subject.CN}' ` + 'does not match our pinned fingerprint'; return new Error(msg); } // This loop is informational only. // Print the certificate and public key fingerprints of all certs in the // chain. Its common to pin the public key of the issuer on the public // internet, while pinning the public key of the service in sensitive // environments. do { console.log('Subject Common Name:', cert.subject.CN); console.log(' Certificate SHA256 fingerprint:', cert.fingerprint256); hash = crypto.createHash('sha256'); console.log(' Public key ping-sha256:', sha256(cert.pubkey)); lastprint256 = cert.fingerprint256; cert = cert.issuerCertificate; } while (cert.fingerprint256 !== lastprint256); }, }; options.agent = new https.Agent(options); const req = https.request(options, (res) => { console.log('All OK. Server matched our pinned cert or public key'); console.log('statusCode:', res.statusCode); res.on('data', (d) => {}); }); req.on('error', (e) => { console.error(e.message); }); req.end();
範例輸出:
Subject Common Name: github.com
Certificate SHA256 fingerprint: FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65
Public key ping-sha256: SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
Subject Common Name: Sectigo ECC Domain Validation Secure Server CA
Certificate SHA256 fingerprint: 61:E9:73:75:E9:F6:DA:98:2F:F5:C1:9E:2F:94:E6:6C:4E:35:B6:83:7C:E3:B9:14:D2:24:5C:7F:5F:65:82:5F
Public key ping-sha256: Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
Subject Common Name: USERTrust ECC Certification Authority
Certificate SHA256 fingerprint: A6:CF:64:DB:B4:C8:D5:FD:19:CE:48:89:60:68:DB:03:B5:33:A8:D1:33:6C:62:56:A8:7D:00:CB:B3:DE:F3:EA
Public key ping-sha256: UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
Subject Common Name: AAA Certificate Services
Certificate SHA256 fingerprint: D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4
Public key ping-sha256: vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
All OK. Server matched our pinned cert or public key
statusCode: 200