Flutter:如何解决HTTPS证书验证失败的GET请求问题
解决Flutter中GET请求的证书验证失败问题
你遇到的这个CERTIFICATE_VERIFY_FAILED错误,本质是客户端无法验证mocky.io的SSL证书链,可能是设备/模拟器的根证书库缺少对应签发机构的证书,或者测试环境下的临时配置问题。我给你分几种场景的解决方案,适配不同的开发阶段:
一、临时调试方案(仅用于本地开发,绝对不能上线)
如果你只是想快速验证API逻辑,暂时绕过证书验证是最快的方式。我们可以创建一个自定义的HttpClient,通过badCertificateCallback信任所有证书,再把它包装成http库可用的Client:
import 'dart:convert'; import 'package:http/http.dart' as http; import 'dart:io'; import 'package:flutter/services.dart'; Future<void> _fetchPost() async { // 创建自定义HttpClient,绕过证书验证 HttpClient httpClient = HttpClient() ..badCertificateCallback = ((X509Certificate cert, String host, int port) => true); // 包装成http.Client http.Client client = http.IOClient(httpClient); try { http.Response response = await client.get(Uri.parse(url)); print(response.body); setState(() { var convertDatatoJson = json.decode(response.body); debugPrint(convertDatatoJson.toString()); _data = convertDatatoJson['table_menu_list']; }); } catch (e) { debugPrint('请求出错: $e'); } finally { // 务必关闭client,避免资源泄漏 client.close(); } }
⚠️ 注意:这个方法会完全跳过证书验证,存在被中间人攻击的风险,绝对不能用于生产环境。
二、生产环境的正规解决方案
1. 检查设备/模拟器的根证书
mocky.io使用的是正规的SSL证书(由DigiCert签发),大部分真机的系统根证书库已经包含这个签发机构的证书,所以首先可以尝试:
- 更新安卓模拟器的系统版本到较新的版本(比如Android 10+)
- 在真实设备上测试,真机的根证书库通常会自动更新
如果还是不行,就用下面的自定义证书方案。
2. 嵌入根证书到App中
我们可以把mocky.io证书的根证书打包到App里,让App只信任这个合法的根证书,既保证安全又能解决验证问题:
- 先下载DigiCert Global Root CA证书(可以通过浏览器访问mocky.io,点击地址栏的锁图标导出根证书),保存为
digicert_root_ca.pem,放到项目的assets目录下 - 在
pubspec.yaml中配置assets:
flutter: assets: - assets/digicert_root_ca.pem
- 修改请求代码,加载自定义证书并验证:
import 'dart:convert'; import 'package:http/http.dart' as http; import 'dart:io'; import 'package:flutter/services.dart'; Future<void> _fetchPost() async { // 从assets加载根证书 ByteData certData = await rootBundle.load('assets/digicert_root_ca.pem'); SecurityContext securityContext = SecurityContext.defaultContext; // 设置信任的根证书 securityContext.setTrustedCertificatesBytes(certData.buffer.asUint8List()); HttpClient httpClient = HttpClient(context: securityContext); http.Client client = http.IOClient(httpClient); try { http.Response response = await client.get(Uri.parse(url)); print(response.body); setState(() { var convertDatatoJson = json.decode(response.body); debugPrint(convertDatatoJson.toString()); _data = convertDatatoJson['table_menu_list']; }); } catch (e) { debugPrint('请求出错: $e'); } finally { client.close(); } }
这个方法只信任指定的合法根证书,完全符合生产环境的安全要求。
三、可选:使用Dio库简化配置
如果你觉得原生http库的配置有点繁琐,可以试试Dio库,它对证书验证的配置更灵活:
开发环境临时绕过:
import 'dart:convert'; import 'package:dio/dio.dart'; import 'dart:io'; Future<void> _fetchPost() async { Dio dio = Dio(); dio.httpClientAdapter = DefaultHttpClientAdapter() ..onHttpClientCreate = (HttpClient client) { // 临时绕过证书验证 client.badCertificateCallback = ((cert, host, port) => true); return client; }; try { Response response = await dio.get(url); print(response.data); setState(() { var convertDatatoJson = response.data; debugPrint(convertDatatoJson.toString()); _data = convertDatatoJson['table_menu_list']; }); } catch (e) { debugPrint('请求出错: $e'); } }
生产环境加载自定义证书:
Dio的配置逻辑和http库类似,同样可以加载assets中的根证书,只需要在onHttpClientCreate里配置SecurityContext即可。
内容的提问来源于stack exchange,提问作者AllwiN
相关产品推荐
相关产品推荐

