node.js https请求报cert_has_expired或unable_to_verify_leaf_signature错误,根本原因是tls证书验证失败,常见于系统根证书缺失/过期、node.js未正确加载ca证书包、或目标服务证书配置异常;vscode终端、调试器及插件均复用同一tls逻辑,需按环境(windows/macos/linux)分别检查系统时间、证书路径、node_extra_ca_certs配置及进程上下文继承性。

Node.js HTTPS 请求报 CERT_HAS_EXPIRED 或 UNABLE_TO_VERIFY_LEAF_SIGNATURE
这类错误不是 VSCode 本身的问题,而是 Node.js 运行时在发起 HTTPS 请求时,无法验证服务器证书链——通常因为系统根证书缺失、过期,或 Node.js 没加载到正确的 CA 证书包。VSCode 内置终端、调试器、插件(如 REST Client、LeetCode)调用 node 执行时都会复用同一套 TLS 验证逻辑。
- 先确认是否真是证书问题:在 VSCode 终端中运行
node -e "require('https').get('https://httpbin.org/get', r => r.on('data', console.log))",若抛出CERT_HAS_EXPIRED、UNABLE_TO_VERIFY_LEAF_SIGNATURE或DEPTH_ZERO_SELF_SIGNED_CERT,基本可锁定 - 注意区分:如果仅某个代理/内网服务报错,而公网地址(如 https://httpbin.org)正常,则更可能是目标服务用了自签名或私有 CA,而非全局根证书缺失
- Windows 用户尤其容易踩坑:Node.js 默认使用 Windows CryptoAPI 获取系统证书,但若系统证书存储损坏、或企业策略禁用了某些根 CA(如 Sectigo、DigiCert 新根),Node 就会失败;macOS/Linux 则依赖 OpenSSL 的
ca-bundle.crt路径
检查 Node.js 实际使用的 CA 证书路径
Node.js 启动时会按顺序查找 CA 证书源,顺序错了就可能跳过你更新的证书。执行以下命令查看当前生效路径:
node -p "require('crypto').constants.SSL_OP_NO_TLSv1_3"
这本身不输出路径,但配合环境变量更有效:
微软正式发布 Visual Studio Code 1.118 版本 。本次更新重点强化了 AI 开发体验与企业管理能力,其中最引人注目的是新增 Copilot CLI 远程控制功能,允许开发者通过手机或网页远程监控和接管 AI 会话 。同时,为了提高 AI 的运行性价比,新版本优化了令牌缓存策略以降低成本 。此外,1.118 版还引入了 Chronicle 本地历史追踪、TypeScript 7.0 支持以及更严格的企业级访问管控 。
- 运行
node -p "process.env.NODE_EXTRA_CA_CERTS":若返回非空字符串,说明已手动指定证书文件,优先级最高 - 运行
node -p "require('tls').rootCertificates.length":返回数字,正常应 ≥ 100;若为 0 或极小(如 1~2),说明 CA 包根本没加载成功 - 检查
node -p "require('https').globalAgent.options.ca":返回null表示用默认系统 CA;返回数组则说明已被显式覆盖
Windows 上修复根证书缺失(nvm-windows / 手动安装场景)
nvm-windows 默认不重装系统证书,且 Node.js 安装包(尤其是旧版)自带的 ca.pem 已严重过期。手动补救最直接:
- 下载最新 Mozilla CA 包:https://www.php.cn/link/5fe4dadcdb001d8566cd20e6d8a20251,保存为
C: ode-cacacert.pem(路径无空格、无中文) - 在 VSCode 设置(
settings.json)中添加:"terminal.integrated.env.windows": { "NODE_EXTRA_CA_CERTS": "C:\node-ca\cacert.pem" } - 调试时需额外注入:在
launch.json的env字段里加"NODE_EXTRA_CA_CERTS": "C:\node-ca\cacert.pem",否则调试器进程不继承终端环境变量 - 避免改
http.Agent代码绕过校验:临时设rejectUnauthorized: false只能用于开发,上线等于裸奔
macOS/Linux 下证书更新不生效的典型原因
Homebrew 安装的 Node.js 通常依赖系统 OpenSSL,但 macOS Sequoia 后系统证书管理逻辑变更,导致 update-ca-certificates 或 brew reinstall openssl 不一定同步到 Node.js:
- 确认 Node.js 是否用 Homebrew OpenSSL:运行
node -p "require('crypto').getDiffieHellman('modp15')"不报错才说明 OpenSSL 正常加载;若报Error: Cannot find module 'crypto',说明二进制链接异常 - 不要依赖
export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt:macOS 根本没有这个路径,正确路径是/etc/ssl/cert.pem(由security find-certificate -p -s -t > /etc/ssl/cert.pem生成) - VSCode 从 Dock 启动时,不会读取
~/.zshrc中的环境变量:必须通过code .从终端启动,或在settings.json中显式设置terminal.integrated.env.linux/terminal.integrated.env.osx
真正麻烦的不是找不到证书,而是不同上下文(终端、调试器、插件进程)各自加载 CA 的路径和时机完全不同。一个 NODE_EXTRA_CA_CERTS 环境变量,在终端里生效,不代表调试器或 LeetCode 插件就能看到。










