Node.js v20.20.6 文档


HTTPS#>

源代码: lib/https.js

HTTPS 是基于 TLS/SSL 的 HTTP 协议。在 Node.js 中,这是作为一个独立模块实现的。

【HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a separate module.】

确定加密支持是否不可用#>

【Determining if crypto support is unavailable】

Node.js 有可能在构建时不包含对 node:crypto 模块的支持。在这种情况下,尝试从 https 导入或调用 require('node:https') 将会导致抛出错误。

【It is possible for Node.js to be built without including support for the node:crypto module. In such cases, attempting to import from https or calling require('node:https') will result in an error being thrown.】

使用 CommonJS 时,可以使用 try/catch 捕获抛出的错误:

【When using CommonJS, the error thrown can be caught using try/catch:】

let https;
try {
  https = require('node:https');
} catch (err) {
  console.error('https support is disabled!');
} 

在使用词法 ESM import 关键字时,只有在尝试加载模块之前(例如使用预加载模块)注册了 process.on('uncaughtException') 的处理程序,才能捕获该错误。

【When using the lexical ESM import keyword, the error can only be caught if a handler for process.on('uncaughtException') is registered before any attempt to load the module is made (using, for instance, a preload module).】

在使用 ESM 时,如果代码有可能在未启用加密支持的 Node.js 版本上运行,考虑使用 import() 函数替代词法 import 关键字:

【When using ESM, if there is a chance that the code may be run on a build of Node.js where crypto support is not enabled, consider using the import() function instead of the lexical import keyword:】

let https;
try {
  https = await import('node:https');
} catch (err) {
  console.error('https support is disabled!');
} 

类:https.Agent#>

【Class: https.Agent

一个用于 HTTPS 的 Agent 对象,类似于 http.Agent。有关更多信息,请参阅 https.request()

【An Agent object for HTTPS similar to http.Agent. See https.request() for more information.】

new Agent([options])#>

  • options <Object> 可以在代理上设置的一组可配置选项。可以具有与 http.Agent(options) 相同的字段,并且
    • maxCachedSessions <number> 最大 TLS 缓存会话数量。使用 0 可禁用 TLS 会话缓存。默认值: 100

    • servername <string> 要发送到服务器的 服务器名称指示扩展 值。使用空字符串 '' 可以禁用发送该扩展。默认值: 目标服务器的主机名,除非目标服务器使用 IP 地址指定,在这种情况下默认值为 ''(无扩展)。

      有关 TLS 会话重用的信息,请参见 Session Resumption

事件:'keylog'#>

【Event: 'keylog'

  • line <Buffer> ASCII 文本行,采用 NSS SSLKEYLOGFILE 格式。
  • tlsSocket <tls.TLSSocket> 它被生成的 tls.TLSSocket 实例。

keylog 事件在由此代理管理的连接生成或接收密钥材料时触发(通常在握手完成之前,但不一定)。这些密钥材料可以存储用于调试,因为它允许解密捕获的 TLS 流量。对于每个套接字,它可能会被触发多次。

【The keylog event is emitted when key material is generated or received by a connection managed by this agent (typically before handshake has completed, but not necessarily). This keying material can be stored for debugging, as it allows captured TLS traffic to be decrypted. It may be emitted multiple times for each socket.】

一个典型的用例是将接收到的行追加到一个通用的文本文件中,该文件随后被软件(例如 Wireshark)用来解密流量:

【A typical use case is to append received lines to a common text file, which is later used by software (such as Wireshark) to decrypt the traffic:】

// ...
https.globalAgent.on('keylog', (line, tlsSocket) => {
  fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 });
}); 

类:https.Server#>

【Class: https.Server

有关更多信息,请参见http.Server

【See http.Server for more information.】

server.close([callback])#>

请参阅 node:http 模块中的 server.close()

【See server.close() in the node:http module.】

server[Symbol.asyncDispose]()#>

稳定性: 1 - 实验性

调用 server.close() 并返回一个在服务器关闭时完成的 Promise。

【Calls server.close() and returns a promise that fulfills when the server has closed.】

server.closeAllConnections()#>

请参阅 node:http 模块中的 server.closeAllConnections()

【See server.closeAllConnections() in the node:http module.】

server.closeIdleConnections()#>

请参阅 node:http 模块中的 server.closeIdleConnections()

【See server.closeIdleConnections() in the node:http module.】

server.headersTimeout#>

请参阅 node:http 模块中的 server.headersTimeout

【See server.headersTimeout in the node:http module.】

server.listen()#>

启动 HTTPS 服务器以监听加密连接。此方法与 net.Server 中的 server.listen() 完全相同。

【Starts the HTTPS server listening for encrypted connections. This method is identical to server.listen() from net.Server.】

server.maxHeadersCount#>

请参阅 node:http 模块中的 server.maxHeadersCount

【See server.maxHeadersCount in the node:http module.】

server.requestTimeout#>

请参阅 node:http 模块中的 server.requestTimeout

【See server.requestTimeout in the node:http module.】

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

请参阅 node:http 模块中的 server.setTimeout()

【See server.setTimeout() in the node:http module.】

server.timeout#>

  • <number> 默认: 0(无限时间)

请参阅 node:http 模块中的 server.timeout

【See server.timeout in the node:http module.】

server.keepAliveTimeout#>

请参阅 node:http 模块中的 server.keepAliveTimeout

【See server.keepAliveTimeout in the node:http module.】

https.createServer([options][, requestListener])#>

// curl -k https://localhost: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://localhost: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);

或者

【Or】

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

要为此示例生成证书和密钥,则运行:

【To generate the certificate and key for this example, run:】

openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
  -keyout private-key.pem -out certificate.pem 

然后,要为此示例生成 pfx 证书,请运行:

【Then, to generate the pfx certificate for this example, run:】

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

http.get(),但用于 HTTPS。

【Like http.get() but for 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.Agent 实例,用于所有 HTTPS 客户端请求。与默认 https.Agent 配置不同的是,它启用了 keepAlive 并将 timeout 设置为 5 秒。

【Global instance of https.Agent for all HTTPS client requests. Diverges from a default https.Agent configuration by having keepAlive enabled and a timeout of 5 seconds.】

https.request(options[, callback])#>

https.request(url[, options][, callback])#>

触发请求到安全的 Web 服务器。

【Makes a request to a secure web server.】

tls.connect()的以下附加options也被接受: cacertciphersclientCertEngine(已弃用)、crldhparamecdhCurvehonorCipherOrderkeypassphrasepfxrejectUnauthorizedsecureOptionssecureProtocolservernamesessionIdContexthighWaterMark

【The following additional options from tls.connect() are also accepted: ca, cert, ciphers, clientCertEngine (deprecated), 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() 选项的示例:

【Example using options from 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 来选择不使用连接池。

【Alternatively, opt out of connection pooling by not using an 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 的示例:

【Example using a URL as options:】

const options = new URL('https://abc:xyz@example.com');

const req = https.request(options, (res) => {
  // ...
}); 

在证书指纹上进行示例固定,或在公钥上进行固定(类似于 pin-sha256):

【Example pinning on certificate fingerprint, or the public key (similar to 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();

示例的输出:

【Outputs for example:】

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 
Node.js 中文网 - 粤ICP备13048890号