Flutter/Dart请求未格式化JSON时出现XMLHttpRequest错误排查
问题:Flutter发起HTTP请求遇XMLHttpRequest错误,自定义Node服务无法正常返回数据
Dart/Flutter请求代码
Future<List<News>?> getNews() async { var client = http.Client(); var uri = Uri.parse('http://localhost:3000/news'); var response = await client.get(uri); if (response.statusCode == 200) { var jsonFile = response.body; try { return newsFromJson(jsonFile); } catch (e) { print(e); } } return null; }
数据源JSON文件
{ "news": [ { "id": 0, "title": "Test", "text": "Test", "buttonText": "Test", "source": "Test", "showButton": false, "openFile": false, "openWebsite": true }, { "id": 1, "title": "Test", "text": "Test", "buttonText": "Test", "source": "Test", "showButton": false, "openFile": false, "openWebsite": true } ] }
自定义Node.js服务代码
const express = require('express'); const fs = require('fs'); const app = express(); app.get('/news', (req, res) => { console.log('Received request'); fs.readFile('data.json', (err, data) => { if (err) throw err; const news = JSON.parse(data).news; res.json(news); }); }); app.listen(3000, () => { console.log('Server listening on port 3000'); });
补充的JSON解析代码
List<News> newsFromJson(String str) = List<News>.from(json.decode(str).map((x) => News.fromJson(x)));
报错信息
Error: XMLHttpRequest error. C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 299:10 createErrorWithStack C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 341:28 _throw C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/core/errors.dart 116:5 throwWithStackTrace C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1378:11 callback C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15 <fn>
疑问
自定义Node.js服务运行正常,请求能到达服务端,但Flutter端出现XMLHttpRequest错误。用json-server加载同一份JSON文件时,浏览器访问返回格式化JSON,Flutter代码也能正常运行。怀疑是自定义服务返回的JSON未格式化导致问题,请问问题出在哪里?
解决方案
问题根本不是JSON格式化的问题,而是**跨域资源共享(CORS)**限制。Flutter Web在浏览器环境下发起跨域请求时,会受到浏览器的同源策略限制,json-server默认已经配置了CORS相关响应头,允许跨域请求;而你的自定义Node.js服务没有添加CORS支持,所以浏览器拦截了请求,抛出XMLHttpRequest错误。
解决步骤:
- 安装CORS中间件
在Node.js项目目录下执行:
npm install cors
- 修改Node.js服务代码,引入并使用cors中间件
const express = require('express'); const fs = require('fs'); const cors = require('cors'); // 引入cors const app = express(); app.use(cors()); // 全局启用CORS app.get('/news', (req, res) => { console.log('Received request'); fs.readFile('data.json', (err, data) => { if (err) throw err; const news = JSON.parse(data).news; res.json(news); }); }); app.listen(3000, () => { console.log('Server listening on port 3000'); });
- 重启Node.js服务,重新运行Flutter Web项目,此时请求应该能正常获取数据。
另外,如果你想让自定义服务返回格式化的JSON,可以在初始化app后添加配置,这只是优化返回格式,不影响错误修复:
const app = express(); app.use(cors()); app.set('json spaces', 2); // 启用JSON格式化输出
内容的提问来源于stack exchange,提问作者Thoxh
相关产品推荐
相关产品推荐

