Flutter Web端使用http包请求网络报XMLHttpRequest error问题
解决Flutter Web端使用http包请求资源时的XMLHttpRequest error错误
问题场景
使用http包的get方法请求远程图片资源,移动端运行正常,但Web端抛出Error: XMLHttpRequest error错误,相关代码如下:
请求图片的代码:
var companyLogoResponse = await http.get( Uri.parse( "https://stock.znindia.com/assets/assets/logo.png"), ); var companyLogo = companyLogoResponse.bodyBytes;
用于展示图片的代码:
Container( padding: const EdgeInsets.all(4), height: 100, width: 100, child: Image(MemoryImage(companyLogo), fit: BoxFit.fitWidth), ),
错误原因
Web端的网络请求受**跨域资源共享(CORS)**规则限制:浏览器会拦截跨域的XMLHttpRequest请求(http包在Web端底层依赖XMLHttpRequest),如果目标服务器未配置允许当前Web域名的跨域请求,就会触发这个错误。
解决方案
1. 配置目标服务器的CORS规则(生产环境首选)
在目标服务器(此处为stock.znindia.com)添加CORS响应头,允许你的Web域名访问资源:
- 添加响应头
Access-Control-Allow-Origin: 你的Web域名(比如https://your-web-app.com),开发环境可临时用*允许所有域名,但生产环境不建议。 - 不同服务器的配置方式:
- Nginx:在配置文件的
server块中添加add_header Access-Control-Allow-Origin https://your-web-app.com; - 后端框架(如Spring Boot):通过CorsFilter或注解配置允许的域名、请求方法等。
- Nginx:在配置文件的
2. 开发环境使用代理绕过跨域
在Flutter项目根目录创建proxy.config.json文件,内容如下:
{ "/assets": { "target": "https://stock.znindia.com", "changeOrigin": true } }
然后启动项目时指定代理配置:
flutter run -d chrome --web-proxy-config proxy.config.json
同时修改请求代码为相对路径:
var companyLogoResponse = await http.get(Uri.parse("/assets/assets/logo.png"));
3. 针对Web端改用dart:html的HttpRequest API
通过条件导入,在Web端直接使用浏览器原生的HttpRequest,避免http包的封装限制:
import 'dart:typed_data'; import 'package:flutter/foundation.dart'; Future<Uint8List> fetchCompanyLogo() async { if (kIsWeb) { import 'dart:html' as html; final request = await html.HttpRequest.request( "https://stock.znindia.com/assets/assets/logo.png", responseType: "arraybuffer", ); return request.response as Uint8List; } else { // 移动端保留原http包逻辑 var response = await http.get(Uri.parse("https://stock.znindia.com/assets/assets/logo.png")); return response.bodyBytes; } }
4. 直接使用Image.network展示图片(仅适用于图片展示场景)
如果只是为了展示图片,无需提前下载字节流,直接用Image.network替代MemoryImage:
Container( padding: const EdgeInsets.all(4), height: 100, width: 100, child: Image.network( "https://stock.znindia.com/assets/assets/logo.png", fit: BoxFit.fitWidth, ), )
这种方式Web端会用原生<img>标签加载图片,浏览器对图片的跨域限制通常比XMLHttpRequest更宽松,部分场景下可直接解决问题。
内容的提问来源于stack exchange,提问作者Manglam Industrial Product
相关产品推荐
相关产品推荐

