Flutter(Dart)读取Azure Event Grid Namespace遇XMLHttpRequest错误求解决
我正在使用Azure Event Grid Namespace,已将IoT Hub接收的数据通过消息路由转发至该命名空间。尝试用Dart的http.get()请求读取数据并打印响应体时,出现**"Error fetching data: XMLHttpRequest error"**错误。此前在其他Azure服务中通过CORS解决过同类问题,但Azure Event Grid Namespace无CORS功能,现寻求Flutter(Dart)下的替代读取方案。
相关代码
import 'package:http/http.dart' as http; import 'dart:convert'; Future<void> fetchDataFromEventGrid() async { final url = 'https://<namespace name>.<region>.eventgrid.azure.net/api/events'; final apiKey = 'API key'; // 如果你的端点需要API密钥 try { final response = await http.get( Uri.parse(url), headers: { 'Content-Type': 'application/json', 'aeg-sas-key': apiKey, // Azure Event Grid 认证需要aeg-sas-key请求头 }, ); if (response.statusCode == 200) { final data = json.decode(response.body); print('从Event Grid接收的数据: $data'); } else { print('加载数据失败。状态码: ${response.statusCode}'); } } catch (e) { print('获取数据出错: $e'); } } void main() async { await fetchDataFromEventGrid(); }
报错截图

可行的替代方案
1. 搭建后端代理服务
在Flutter应用和Azure Event Grid之间加一层后端服务(比如Dart Shelf、Node.js、Python Flask等),由后端去调用Event Grid的API,Flutter再请求这个后端服务。后端请求不受浏览器CORS规则限制,自然绕开了问题。
示例Dart Shelf代理:
import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; import 'package:http/http.dart' as http; void main() async { var handler = const Pipeline().addMiddleware(logRequests()).addHandler(_proxyRequest); var server = await io.serve(handler, 'localhost', 8080); print('代理服务运行在 http://${server.address.host}:${server.port}'); } Future<Response> _proxyRequest(Request request) async { final eventGridUrl = 'https://<namespace name>.<region>.eventgrid.azure.net/api/events'; final apiKey = '你的API密钥'; final response = await http.get( Uri.parse(eventGridUrl), headers: { 'Content-Type': 'application/json', 'aeg-sas-key': apiKey, }, ); return Response(response.statusCode, body: response.body, headers: {'Content-Type': 'application/json'}); }
Flutter端修改请求地址为代理服务地址:
final url = 'http://localhost:8080';
2. 使用Azure Functions作为中间层
创建一个Azure Function,让它去调用Event Grid Namespace的API,Flutter应用调用这个Function的HTTP触发端点。Azure Functions可以直接配置CORS规则,这样Flutter就能正常发起请求了。
3. 改用Event Grid订阅推送模式
不要主动拉取数据,给Event Grid Namespace创建事件订阅,把数据推送到支持的端点(比如Azure Functions、自定义Webhook)。之后Flutter可以通过WebSocket实时接收数据,或者定期轮询这个端点获取数据。这种方式更贴合Event Grid的设计,也从根源上避免了CORS问题。
4. 尝试用Dio替代http包(辅助方案)
虽然不能直接解决CORS,但Dio提供了更多请求配置选项,你可以尝试替换http包来发起请求,但核心问题还是需要靠中间层解决,这个方法仅作为辅助尝试。
内容的提问来源于stack exchange,提问作者sai

