Node.js v26.0.0 文档
- Node.js v26.0.0
- 目录
- 索引
- 关于本文档
- 用法与示例
- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲区
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入器 API
- 子进程
- 集群
- 命令行选项
- 控制台
- 加密
- 调试器
- 已弃用的 API
- 诊断通道
- DNS
- 域
- 环境变量
- 错误
- 事件
- 文件系统
- 全局对象
- HTTP
- HTTP/2
- HTTPS
- 检查器
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:moduleAPI - 模块:包
- 模块:TypeScript
- 网络
- 可迭代流 API
- 操作系统
- 路径
- 性能钩子
- 权限
- 进程
- Punycode
- 查询字符串
- 逐行读取
- REPL
- 报告
- 单一可执行文件应用
- SQLite
- 流
- 字符串解码器
- 测试运行器
- 定时器
- TLS/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用工具
- V8
- 虚拟机
- WASI
- Web Crypto API
- Web Streams API
- 工作线程
- Zlib
- Zlib 可迭代压缩
- 其他版本
- 选项
HTTPS#
稳定性:2 - 稳定
HTTPS 是基于 TLS/SSL 的 HTTP 协议。在 Node.js 中,它作为单独的模块实现。
确定加密支持是否不可用#
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 连接的方式。
有关重写此方法的详细信息(包括通过回调进行异步套接字创建),请参阅
agent.createConnection()。
new Agent([options])#
options<Object>在代理上设置的可配置选项集。可以包含与http.Agent(options)相同的字段,以及-
maxCachedSessions<number>最大 TLS 缓存会话数。使用0可禁用 TLS 会话缓存。默认值:100。 -
servername<string>要发送到服务器的 服务器名称指示 (SNI) 扩展 的值。使用空字符串''可禁用发送此扩展。默认值:目标服务器的主机名,除非目标服务器是使用 IP 地址指定的,在这种情况下,默认值为''(无扩展)。有关 TLS 会话重用的信息,请参阅
会话恢复 (Session Resumption)。
-
事件:'keylog'#
line<Buffer>ASCII 文本行,采用 NSSSSLKEYLOGFILE格式。tlsSocket<tls.TLSSocket>生成该事件的tls.TLSSocket实例。
当此代理管理的连接生成或接收到密钥材料时,会触发 keylog 事件(通常在握手完成之前,但不一定)。这些密钥材料可以被存储用于调试,因为它允许解密捕获到的 TLS 流量。每个套接字可能会多次触发此事件。
一个典型的用例是将接收到的行追加到一个公共文本文件中,该文件随后被软件(如 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() 并返回一个 Promise,该 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,并且 timeout 为 5 秒。
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 实例是一个可写流。如果需要通过 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() 中的 options 的示例
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 来选择不使用连接池。
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) => {
// ...
});
基于证书指纹或公钥(类似于 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