Flutter模拟器出现NetworkImageLoadException:网络图片加载失败问题求助
搞定NetworkImageLoadException(403)的问题!
嘿,我帮你捋清楚这个403错误的来龙去脉,还有解决办法:
为啥会报403?
你用的via.placeholder.com图片服务器拒绝了Flutter默认的图片请求!很多图片托管平台会校验请求里的User-Agent头,而Flutter自带的NetworkImage默认的请求标识不在这个服务器的允许名单里,直接就给你返回403禁止访问了。
两种解决办法任你选
办法1:换用接口里的缩略图(最快最省事)
jsonplaceholder的photos接口其实给了两个图片地址:url是大图,thumbnailUrl是缩略图。目前缩略图的地址还能正常访问,不用改太多代码:
- 改下
ImageModel的fromJson方法,把取url换成取thumbnailUrl:
ImageModel.fromJson(Map<String, dynamic> parsedJson) { id = parsedJson['id']; title = parsedJson['title']; url = parsedJson['thumbnailUrl']; // 换成缩略图地址 }
这样直接就能加载图片了,适合快速解决问题。
办法2:自定义图片加载器,加合法请求头(要加载大图就用这个)
如果必须要加载那个大图,那我们得给请求加个服务器认可的User-Agent头,需要自定义一个图片加载类:
- 先新建一个
NetworkImageWithHeaders类:
import 'package:flutter/painting.dart'; import 'package:http/http.dart' as http; class NetworkImageWithHeaders extends ImageProvider<NetworkImageWithHeaders> { final String url; final Map<String, String> headers; NetworkImageWithHeaders(this.url, {required this.headers}); @override Future<NetworkImageWithHeaders> obtainKey(ImageConfiguration configuration) { return SynchronousFuture<NetworkImageWithHeaders>(this); } @override ImageStreamCompleter loadImage(NetworkImageWithHeaders key, ImageDecoderCallback decode) { return MultiFrameImageStreamCompleter( codec: _loadAsync(key, decode), scale: 1.0, debugLabel: url, informationCollector: () => <DiagnosticsNode>[ DiagnosticsProperty<ImageProvider>('Image provider', this), DiagnosticsProperty<String>('Image URL', url), ], ); } Future<Codec> _loadAsync(NetworkImageWithHeaders key, ImageDecoderCallback decode) async { final response = await http.get(Uri.parse(url), headers: headers); if (response.statusCode != 200) { throw NetworkImageLoadException(statusCode: response.statusCode, uri: Uri.parse(url)); } return decode(response.bodyBytes); } @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is NetworkImageWithHeaders && other.url == url && other.headers == headers; } @override int get hashCode => Object.hash(url, headers); }
- 然后修改
ImageList里的图片加载代码,用上这个自定义类,加上合法的User-Agent:
Widget build(context) { return ListView.builder( itemCount: images.length, itemBuilder: (context, int index) { return Image( image: NetworkImageWithHeaders( images[index].url, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' }, ), ); }, ); }
小提示
你可以先在浏览器里直接打开那个报403的图片地址,如果浏览器能打开,那肯定就是请求头的问题;如果浏览器也打不开,那说明这个大图地址已经失效了,还是用缩略图更靠谱。
内容的提问来源于stack exchange,提问作者rezli
相关产品推荐
相关产品推荐

