• [Flutter] CachedNetworkImage加载图片证书校验失败


    CachedNetworkImage 在加载某些https网站的图像时会出现类似这样的错误:

    I/flutter: The following HandshakeException was thrown resolving an image codec:
        Handshake error in client (OS Error: 
            CERTIFICATE_VERIFY_FAILED: self signed certificate(handshake.cc:352))
    08-05 16:27:56.673 13676-13696/com.example.flutter_module.host I/flutter: When the exception was thrown, this was the stack:
    08-05 16:27:56.688 13676-13696/com.example.flutter_module.host I/flutter: #0      NetworkImage._loadAsync (package:flutter/src/painting/image_provider.dart:490:39)

    这就是证书问题了。

    CachedNetworkImage 提供了一个参数 cacheManager , 一般我们都不会指定,那么它会使用 DefaultCacheManager 。DefaultCacheManager 中会使用一个 FileService 来下载图像。那么,我们只需要做一个 CacheManager ,并自定义一个 FileService 就可以解决此问题了。具体代码如下:

    import 'dart:async';
    
    import 'package:flutter_cache_manager/flutter_cache_manager.dart';
    import 'package:http/http.dart' as http;
    import 'dart:io';
    
    /// 缓存管理
    class EsoImageCacheManager extends CacheManager {
      static const key = 'libEsoCachedImageData';
    
      static EsoImageCacheManager _instance;
      factory EsoImageCacheManager() {
        _instance ??= EsoImageCacheManager._();
        return _instance;
      }
    
      EsoImageCacheManager._() : super(Config(key, fileService: EsoHttpFileService()));
    }
    
    class EsoHttpFileService extends FileService {
      HttpClient _httpClient;
      EsoHttpFileService({HttpClient httpClient}) {
        _httpClient = httpClient ?? HttpClient();
        _httpClient.badCertificateCallback = (cert, host, port) => true;
      }
    
      @override
      Future<FileServiceResponse> get(String url,
          {Map<String, String> headers = const {}}) async {
        final Uri resolved = Uri.base.resolve(url);
        final HttpClientRequest req = await _httpClient.getUrl(resolved);
        headers?.forEach((key, value) {
          req.headers.add(key, value);
        });
        final HttpClientResponse httpResponse = await req.close();
        final http.StreamedResponse _response = http.StreamedResponse(
          httpResponse.timeout(Duration(seconds: 60)), httpResponse.statusCode,
          contentLength: httpResponse.contentLength,
          reasonPhrase: httpResponse.reasonPhrase,
          isRedirect: httpResponse.isRedirect,
        );
        return HttpGetResponse(_response);
      }
    }

    使用方法:

    CachedNetworkImage(
        imageUrl: url, 
        fit: BoxFit.cover,
        cacheManager: EsoImageCacheManager()
    )

    经测试,问题解决。

  • 相关阅读:
    Maven pom.xml中添加指定的中央仓库
    命令行远程链接MySQL
    A required class was missing while executing org.apache.maven.plugins:maven-war-plugin:2.1.1:war
    mvn deploy命令上传包
    保存好你的密码
    PuTTY免输密码自动登录Linux
    ActiveMQ无法启动
    linux控制台批量杀进程
    dubbo入门之微服务客户端服务端配置
    dubbo入门之helloWorld
  • 原文地址:https://www.cnblogs.com/yangyxd/p/14030803.html
Copyright © 2020-2023  润新知