1. 程式人生 > 實用技巧 >[Flutter] CachedNetworkImage載入圖片證書校驗失敗

[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()
)

經測試,問題解決。