You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Deno fetch请求第三方Web API时遇到TLS握手错误:Received a ServerHelloDone handshake message while expecting [CertificateRequest]

解决Deno fetch请求第三方API时的TLS握手异常(Received a ServerHelloDone while expecting CertificateRequest)

我之前碰到过完全一样的TLS握手问题,折腾了好几个小时才找到可行的解决办法,给你梳理几个方向:

1. 手动指定兼容的TLS版本与加密套件

这个错误大概率是Deno默认的TLS栈(基于rustls)和第三方服务器的非标准TLS配置不兼容导致的——服务器跳过了CertificateRequest直接发送ServerHelloDone,但Deno的预期流程里需要前者。

你可以尝试手动建立TLS连接并指定兼容的版本和加密套件,再基于这个连接发起请求:

// 手动建立兼容的TLS连接
const tlsConn = await Deno.connectTls({
  hostname: "your-third-party-api-domain.com",
  port: 443,
  tls: {
    minVersion: "TLSv1.2", // 强制使用TLS 1.2,很多老服务器只支持这个
    maxVersion: "TLSv1.2",
    cipherSuites: [
      "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
    ], // 选服务器大概率支持的加密套件
  },
});

// 基于自定义连接创建HTTP客户端
const httpClient = new Deno.HttpClient(tlsConn);
const response = await fetch("https://your-third-party-api-domain.com/api/path", {
  client: httpClient,
});

// 后续处理响应
const data = await response.json();
console.log(data);

2. 调整Deno启动时的TLS参数

如果手动配置连接太麻烦,你可以试试用Deno的启动参数强制指定TLS版本,比如强制使用TLS 1.2(很多出现这种异常的服务器都是老版本TLS):

deno run --tls-v1.2 your-fetch-script.ts

如果还是不行,也可以尝试暂时禁用严格的证书检查(注意:这仅用于测试,生产环境谨慎使用):

deno run --unsafely-ignore-certificate-errors your-fetch-script.ts

3. 换用第三方HTTP客户端库

如果上面两种方法都没效果,可能是Deno原生的fetch对这种非标准握手流程处理太严格。你可以试试用Deno生态里的第三方HTTP客户端,比如ky或者适配Deno的axios,它们的TLS处理逻辑可能更灵活:

比如用ky的例子:

import ky from "https://cdn.skypack.dev/ky@0.33.3";

try {
  const data = await ky.get("https://your-third-party-api-domain.com/api/path").json();
  console.log(data);
} catch (err) {
  console.error(err);
}

错误原因补充

这个异常的本质是TLS握手阶段的流程不匹配:Deno的TLS客户端预期服务器发送CertificateRequest消息(用于请求客户端证书),但服务器直接发送了ServerHelloDone结束握手流程,导致客户端无法正常完成握手。这种情况通常出现在配置不规范的第三方服务器上,我们只能通过调整客户端的TLS配置来适配。

内容的提问来源于stack exchange,提问作者chovy

火山引擎 最新活动