Dart发起HTTP请求报HandshakeException握手异常该如何解决?
问题原因
这个错误由Dart HTTP客户端的TLS证书校验失败触发:客户端无法在本地信任的根证书列表中匹配到目标站点证书的颁发机构,通常是目标站点使用自签名证书、小众CA颁发证书或证书链配置不全导致。
解决方案
方案1:本地测试临时跳过证书校验(禁止用于生产环境)
你可以自定义HTTP客户端,跳过证书校验逻辑适配调试场景,修改后代码如下:
import 'dart:io'; import 'package:http/http.dart' as http; import 'package:http/io_client.dart'; void main() async { var testConnection = await connectionTest(); print(testConnection); } Future connectionTest() async { var url = Uri.parse('https://sophia.bc.ufg.br/mobile/busca.php?idioma=ptbr&acesso=web'); try { // 自定义HttpClient,跳过证书校验 final ioClient = HttpClient() ..badCertificateCallback = (X509Certificate cert, String host, int port) => true; // 包装为http包可用的Client final client = IOClient(ioClient); var response = await client.get(url); // 用完记得关闭客户端 client.close(); return response.statusCode; } catch (e) { return e; } }
注意:该方案会关闭所有证书校验逻辑,存在中间人攻击风险,仅可用于本地调试阶段
方案2:生产环境合法校验方案
将目标站点的根证书添加到Dart的信任列表中,实现合法的证书校验:
- 导出目标站点的根证书为PEM格式,保存到项目资源目录
- 加载证书到SecurityContext,再基于此创建HTTP客户端,代码示例如下:
import 'dart:io'; import 'package:flutter/services.dart' show rootBundle; // 纯Dart项目可直接用File读本地证书文件 import 'package:http/http.dart' as http; import 'package:http/io_client.dart'; Future connectionTest() async { var url = Uri.parse('https://sophia.bc.ufg.br/mobile/busca.php?idioma=ptbr&acesso=web'); try { // 加载根证书到安全上下文 final securityContext = SecurityContext.defaultContext; final certData = await rootBundle.load('assets/ssl/sophia_bc_ufg_br_root.pem'); securityContext.setTrustedCertificatesBytes(certData.buffer.asUint8List()); // 基于自定义安全上下文创建客户端 final ioClient = HttpClient(context: securityContext); final client = IOClient(ioClient); var response = await client.get(url); client.close(); return response.statusCode; } catch (e) { return e; } }
如果是Flutter项目,需要提前在pubspec.yaml中声明证书资源路径:
assets: - assets/ssl/sophia_bc_ufg_br_root.pem
内容的提问来源于stack exchange,提问作者Bruno Soares
相关产品推荐
相关产品推荐

