Flutter加载图片报handshake.cc:359自签名证书验证失败如何解决
问题原因
你单独定义的IOClient没有被CachedNetworkImage使用,该库默认使用内部自带的默认HttpClient加载图片,默认的HttpClient会严格校验SSL证书,当你请求的图片服务用了自签名证书时,就会抛出证书验证失败的错误。
解决方案
有两种常用的解决方式,可根据场景选择:
方案1:自定义CacheManager指定HttpClient(推荐)
CachedNetworkImage依赖flutter_cache_manager实现缓存逻辑,你可以自定义CacheManager,传入你配置好的IOClient,所有通过该CacheManager加载的图片都会使用你指定的客户端。
- 首先实现自定义CacheManager:
import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:http/io_client.dart'; import 'dart:io'; class CustomCacheManager extends CacheManager { static const String _cacheKey = 'customImageCache'; static CustomCacheManager? _instance; factory CustomCacheManager() { _instance ??= CustomCacheManager._internal(); return _instance!; } CustomCacheManager._internal() : super( Config( _cacheKey, fileService: HttpFileService( httpClient: IOClient( HttpClient() ..connectionTimeout = const Duration(seconds: 30) ..idleTimeout = const Duration(seconds: 30) ..badCertificateCallback = (X509Certificate cert, String host, int port) => true, ), ), ), ); }
- 在使用
CachedNetworkImage时指定自定义的cacheManager:
CachedNetworkImage( imageUrl: item.thumbnail, fit: BoxFit.cover, cacheManager: CustomCacheManager(), // 加上这一行 httpHeaders: { 'Authorization': 'Bearer ${authProvider.token}', }, errorWidget: (context, _, __) => const Center( child: Icon( Icons.broken_image_rounded, size: 28.0, color: Colors.black54, ), ), )
方案2:全局重写HttpOverrides(适合开发调试用)
如果不需要单独管控图片请求的客户端,也可以全局重写Dart的HttpClient创建逻辑,所有Http请求都会默认跳过证书校验:
import 'dart:io'; import 'package:flutter/material.dart'; void main() { HttpOverrides.global = _DevHttpOverrides(); runApp(const MyApp()); } class _DevHttpOverrides extends HttpOverrides { @override HttpClient createHttpClient(SecurityContext? context) { return super.createHttpClient(context) ..connectionTimeout = const Duration(seconds: 30) ..idleTimeout = const Duration(seconds: 30) ..badCertificateCallback = (X509Certificate cert, String host, int port) => true; } }
注意事项
- 生产环境不要直接设置
badCertificateCallback固定返回true,会导致所有SSL校验失效,存在严重的安全风险。正式上线时建议将服务端的自签名证书加入客户端的可信证书列表,仅对可信域名的证书放行校验。 - 如果你需要全局携带Authorization等请求头,也可以直接加到自定义HttpClient的
defaultHeaders属性中,无需每个CachedNetworkImage都单独传httpHeaders。
内容的提问来源于stack exchange,提问作者Zeke
相关产品推荐
相关产品推荐

