跳到主要内容
ecdsa.com
Node.js tls / https / fetchNode.js crypto 模块

错误信息

Client network socket disconnected before secure TLS connection was established

也可能输出为

  • code: 'ECONNRESET'

使用 fetch() 时,它是“TypeError: fetch failed”的原因;npm 和 yarn 会把它打印在各自的“request to … failed”消息中。同样的文字配上不同的代码(例如 ETIMEDOUT),指向的是超时而不是连接重置。

Node.js tls / https / fetch — code ECONNRESET during the TLS handshake

含义

Node.js 发送 ClientHello 之后、TLS 握手完成之前,对方(或中间的某个设备)关闭了 TCP 连接。由于没有收到 TLS 告警,Node.js 无法说明原因;它报告的是连接重置,代码为 ECONNRESET。原因在服务器、代理或防火墙上,而不在证书上。

原因

修复方法

  1. 1.

    检查代理设置

    把环境中的代理配置与浏览器使用的配置(通常是 PAC 文件)对比。代理 URL 通常应为 http://,内部主机应放进 NO_PROXY。

    bash
    env | grep -i -E '^(https?|no)_proxy='
    npm config get proxy; npm config get https-proxy
    # Proxy URL with http:// and internal hosts in NO_PROXY
    export HTTPS_PROXY=http://proxy.example.net:3128 NO_PROXY=localhost,127.0.0.1,.internal.example.com
  2. 2.

    用 openssl s_client 复现握手

    如果 s_client 也被断开,问题就在网络或服务器上;变换 SNI 的设置,看服务器是否需要它。

    bash
    # Same handshake without Node.js: does the server or network cut it too?
    openssl s_client -connect api.example.com:443 -servername api.example.com -brief </dev/null
    openssl s_client -connect api.example.com:443 -noservername -brief </dev/null
  3. 3.

    让 Node.js 使用代理环境变量

    设置 NODE_USE_ENV_PROXY=1 后,较新的 Node.js 版本会对 http、https 和 fetch 遵循 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY;axios、got 或 undici 的 ProxyAgent 等库有各自的代理选项。

    bash
    # Node.js does not use HTTPS_PROXY by itself; recent releases can be told to
    NODE_USE_ENV_PROXY=1 HTTPS_PROXY=http://proxy.example.net:3128 node app.js

相关错误

浏览完整的签名错误库