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

Flutter模拟器出现NetworkImageLoadException:网络图片加载失败问题求助

搞定NetworkImageLoadException(403)的问题!

嘿,我帮你捋清楚这个403错误的来龙去脉,还有解决办法:

为啥会报403?

你用的via.placeholder.com图片服务器拒绝了Flutter默认的图片请求!很多图片托管平台会校验请求里的User-Agent头,而Flutter自带的NetworkImage默认的请求标识不在这个服务器的允许名单里,直接就给你返回403禁止访问了。

两种解决办法任你选

办法1:换用接口里的缩略图(最快最省事)

jsonplaceholder的photos接口其实给了两个图片地址:url是大图,thumbnailUrl是缩略图。目前缩略图的地址还能正常访问,不用改太多代码:

  1. 改下ImageModel的fromJson方法,把取url换成取thumbnailUrl:
ImageModel.fromJson(Map<String, dynamic> parsedJson) {
  id = parsedJson['id'];
  title = parsedJson['title'];
  url = parsedJson['thumbnailUrl']; // 换成缩略图地址
}

这样直接就能加载图片了,适合快速解决问题。

办法2:自定义图片加载器,加合法请求头(要加载大图就用这个)

如果必须要加载那个大图,那我们得给请求加个服务器认可的User-Agent头,需要自定义一个图片加载类:

  1. 先新建一个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);
}
  1. 然后修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 13:37:34