You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter CachedNetworkImage握手错误求助:后端强制HTTPS后图片加载失败

解决CachedNetworkImage在HTTPS环境下的证书验证失败问题

错误原因

你遇到的CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate错误,本质是客户端无法验证服务器SSL证书的合法性——要么服务器使用自签名证书,要么证书链配置不完整(缺少中间/根证书),导致系统默认信任链无法识别该证书。

解决方案

1. 生产环境:修复服务器证书配置(推荐)

这是最安全合规的根源解决方案:

  • 为服务器部署由可信CA颁发的证书(比如Let's Encrypt的免费证书)
  • 检查服务器SSL配置,确保证书链完整(包含所有必要的中间证书),避免出现“无法获取本地颁发者证书”的情况

2. 开发环境:临时绕过证书验证(仅测试用)

如果是开发测试阶段,可临时让HttpClient忽略证书校验,但绝对禁止在生产环境使用:

// 创建忽略证书验证的HttpClient
HttpClient createInsecureHttpClient() {
  return HttpClient()
    ..badCertificateCallback =
        (X509Certificate cert, String host, int port) => true;
}

// 修改CachedNetworkImage代码,传入自定义HttpClient
CachedNetworkImage(
  imageUrl: addr,
  progressIndicatorBuilder: (context, url, downloadProgress) =>
      CircularProgressIndicator.adaptive(value: downloadProgress.progress),
  errorWidget: (context, url, error) => const Icon(Icons.error),
  httpHeaders: RuntimeMetadata.getTokenAsWholeMap(),
  httpClient: createInsecureHttpClient(), // 添加此行
);

3. 私有环境:信任指定自签名证书

如果服务器使用自签名证书且为内部私有部署,可将证书打包到应用中,让HttpClient仅信任该证书:

  1. 将证书文件(如server_cert.pem)放入项目assets目录,在pubspec.yaml中声明资源:
assets:
  - assets/server_cert.pem
  1. 加载证书并配置HttpClient:
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'dart:io';

Future<HttpClient> createTrustedHttpClient() async {
  // 加载本地证书
  final ByteData certData = await rootBundle.load('assets/server_cert.pem');
  final X509Certificate trustedCert = X509Certificate.fromPem(
    certData.buffer.asUint8List().toString(),
  );

  return HttpClient()
    ..badCertificateCallback = (X509Certificate cert, String host, int port) {
      // 仅信任指定证书
      return cert.pem == trustedCert.pem;
    };
}

// 使用时传入自定义HttpClient
CachedNetworkImage(
  imageUrl: addr,
  progressIndicatorBuilder: (context, url, downloadProgress) =>
      CircularProgressIndicator.adaptive(value: downloadProgress.progress),
  errorWidget: (context, url, error) => const Icon(Icons.error),
  httpHeaders: RuntimeMetadata.getTokenAsWholeMap(),
  httpClient: await createTrustedHttpClient(),
);

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 09:55:19