在 Flutter 中,尝试使用NetworkImage从(开发)服务器(没有证书的 HTTPS)加载图像- 导致抛出异常:客户端中的握手错误(操作系统错误:CERTIFICATE_VERIFY_FAILED:ok(handshake.cc:355))
是否有解决方法,类似于它在HTTPClient 中的完成方式?httpClient.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
这是为后来出现在这里的人准备的。我只是帮助其他人使用@Alexey 所说的 NetworkImageSSL 的完整代码(他给出的优秀解决方案)。
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui show instantiateImageCodec, Codec;
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
class NetworkImageSSL extends ImageProvider<NetworkImageSSL> {
const NetworkImageSSL(this.url, {this.scale = 1.0, this.headers})
: assert(url != null),
assert(scale != null);
final String url;
final double scale;
final Map<String, String> headers;
@override
Future<NetworkImageSSL> obtainKey(ImageConfiguration configuration) {
return new SynchronousFuture<NetworkImageSSL>(this);
}
@override
ImageStreamCompleter load(NetworkImageSSL key, DecoderCallback decode) {
return MultiFrameImageStreamCompleter(codec: _loadAsync(key), scale: key.scale);
}
static final HttpClient _httpClient = new HttpClient()
..badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
Future<ui.Codec> _loadAsync(NetworkImageSSL key) async {
assert(key == this);
final Uri resolved = Uri.base.resolve(key.url);
final HttpClientRequest request = await _httpClient.getUrl(resolved);
headers?.forEach((String name, String value) {
request.headers.add(name, value);
});
final HttpClientResponse response = await request.close();
if (response.statusCode != HttpStatus.ok)
throw new Exception(
'HTTP request failed, statusCode: ${response?.statusCode}, $resolved');
final Uint8List bytes = await consolidateHttpClientResponseBytes(response);
if (bytes.lengthInBytes == 0)
throw new Exception('NetworkImageSSL is an empty file: $resolved');
return await ui.instantiateImageCodec(bytes);
}
@override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType) return false;
final NetworkImageSSL typedOther = other;
return url == typedOther.url && scale == typedOther.scale;
}
@override
int get hashCode => hashValues(url, scale);
@override
String toString() => '$runtimeType("$url", scale: $scale)';
}
Run Code Online (Sandbox Code Playgroud)
是的,有一个简单的解决方案。只需将源代码复制并粘贴class NetworkImage到您的代码库中,然后修改它以接受任何 SSL。
它位于/flutter/packages/flutter/lib/src/painting/image_provider.dart
将其重命名为类似名称NetworkImageSSL以避免与原始类发生名称冲突。那么,在这堂课中你会发现
static final HttpClient _httpClient = new HttpClient();
将其替换为
static final HttpClient _httpClient = new HttpClient()
..badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
在编译之前包含必要的包(您可以从 复制相关导入image_provider.dart)。现在您可以按如下方式加载图像:
new Image(image: NetworkImageSSL(thumbURL), fit: BoxFit.cover)
| 归档时间: |
|
| 查看次数: |
4374 次 |
| 最近记录: |