代理环境下Node.js请求报self signed certificate in certificate chain错误如何解决
问题根因
- 公司网络部署了SSL中间人代理,所有出站HTTPS请求都会被代理拦截,证书链会被替换为公司自签证书。
- Postman默认调用Windows系统的受信任根证书池,你已经提前信任了公司根证书,所以直接请求正常。
- Node.js运行时自带独立的根证书池,默认不会读取系统受信任的证书列表,所以发起HTTPS请求时会校验证书失败,抛出自签证书错误。
- 你之前尝试的
npm config相关配置仅作用于npm包下载流程,对Node运行时发起的业务请求不生效;set命令设置的环境变量为当前终端窗口临时生效,重启终端或通过其他方式启动Node服务就会失效。
可行解决方案
优先使用第一种方案,对项目无侵入且不会影响其他Node项目运行:
方案1:给axios单独配置根证书(最稳定)
- 导出公司自签根证书:用浏览器访问
https://jsonplaceholder.typicode.com/posts,点击地址栏的锁图标 → 证书 → 证书路径 → 选中最顶层的根证书 → 查看证书 → 详细信息 → 复制到文件 → 选择Base64编码的X.509格式,保存为company-root.crt存到项目根目录。 - 修改请求代码,配置axios信任该根证书:
const fs = require('fs'); const https = require('https'); // 读取本地存储的公司根证书 const companyRootCA = fs.readFileSync('./company-root.crt'); // 自定义HTTPS Agent const customHttpsAgent = new https.Agent({ ca: companyRootCA // 仅测试临时排查可以加 rejectUnauthorized: false,生产环境禁止使用 }); exports.testing = async(req, res, next) => { try { const data = await axios.get("https://jsonplaceholder.typicode.com/posts", { httpsAgent: customHttpsAgent, // 如果需要手动指定代理,补充以下配置,替换为你公司的代理地址和端口 // proxy: { // host: '127.0.0.1', // port: 1080 // } }) console.log({"Data": data.data}) }catch(err){ console.error({"ERROR": err}); } }
方案2:永久配置Node全局环境变量
适合所有本地Node项目都要走公司代理的场景:
- 打开Windows系统环境变量配置面板,新建系统变量:
- 变量名
NODE_EXTRA_CA_CERTS,变量值填你导出的公司根证书的完整绝对路径,比如C:\dev\certs\company-root.crt - 开发测试环境可以额外新建变量
NODE_TLS_REJECT_UNAUTHORIZED,值为0,生产环境禁止配置该变量
- 变量名
- 配置完成后重启所有终端窗口,重新启动Node服务即可生效。
方案3:使用全局代理适配工具
可以安装global-agent等npm包,全局注入代理和证书配置,不需要修改业务代码,适合多项目批量配置的场景。
内容的提问来源于stack exchange,提问作者user10698867
相关产品推荐
相关产品推荐

