Flutter Web中HTTP请求导致客户端崩溃问题排查求助
Flutter Web HTTP请求崩溃问题排查与解决
问题现象
- Flutter Web(Chrome环境)发起POST请求,服务器正常返回400状态码,但客户端直接崩溃,无法执行后续状态判断逻辑
- 使用curl或浏览器直接访问服务器一切正常
- 用try语句包裹代码后捕获到错误:
ClientException: XMLHttpRequest error., uri=http://127.0.0.1/api/submitphone - Wireshark抓包发现请求先发送OPTIONS而非POST
- 即使发起最基础的GET请求访问本地Python服务器(
python -m http.server 80),返回200状态码时仍会崩溃
排查与解决步骤
1. 处理CORS跨域问题(核心原因)
浏览器在跨域场景下(比如Flutter Web的端口和服务器端口不同),会对带自定义头(如Content-Type: application/json)的请求先发起OPTIONS预请求,验证服务器是否允许跨域。如果服务器没有配置CORS响应头,OPTIONS请求会失败,进而触发XMLHttpRequest错误,导致Flutter Web崩溃。
解决方法:
自定义后端服务:添加CORS响应头,以Python Flask为例:
from flask import Flask from flask_cors import CORS app = Flask(__name__) # 开发环境允许所有来源,生产环境需指定具体域名 CORS(app, resources={r"/api/*": {"origins": "*"}})也可以手动添加响应头:
@app.after_request def after_request(response): response.headers.add('Access-Control-Allow-Origin', '*') response.headers.add('Access-Control-Allow-Methods', 'GET, POST, OPTIONS') response.headers.add('Access-Control-Allow-Headers', 'Content-Type') return response注意:OPTIONS请求必须返回200状态码,不能返回404或其他错误。
Python本地HTTP服务器:替换默认服务器为支持CORS的自定义服务,创建以下脚本运行:
from http.server import HTTPServer, SimpleHTTPRequestHandler class CORSRequestHandler(SimpleHTTPRequestHandler): def end_headers(self): self.send_header('Access-Control-Allow-Origin', '*') self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS') self.send_header('Access-Control-Allow-Headers', 'Content-Type') super().end_headers() def do_OPTIONS(self): self.send_response(200) self.end_headers() if __name__ == '__main__': server = HTTPServer(('0.0.0.0', 80), CORSRequestHandler) server.serve_forever()
2. 完善Flutter代码的错误处理
未捕获的异常会直接导致客户端崩溃,必须用try-catch包裹请求逻辑,确保能处理所有异常:
static Future<TradApiServerResponse> submitPhone(String phone, String code) async { try { http.Response response = await http.post( Uri.parse("$urlbase/api/submitphone"), headers: <String, String>{ 'Content-Type': 'application/json; charset=UTF-8', }, body: jsonEncode(<String, String>{ 'code': code, 'phone': phone, }), ); if (response.statusCode == 200) { // 处理正常响应逻辑 } else { // 处理非200状态码,如400错误 throw Exception("服务器返回错误:${response.statusCode}"); } } catch (e) { // 捕获请求异常,包括CORS错误、网络错误等 print("请求失败:$e"); // 可返回错误状态或重新抛出给上层处理 rethrow; } }
3. 利用Chrome开发者工具定位问题
打开Chrome DevTools(F12):
- 切换到Network标签,查看OPTIONS请求的响应状态和头信息,确认是否返回200且带有正确的CORS头
- 切换到Console标签,查看更详细的浏览器原生错误信息,比Flutter的错误栈更直观
4. 排除浏览器插件干扰
部分浏览器插件(如广告拦截器、CORS拦截工具)可能会影响请求,尝试禁用所有插件后重新测试。
内容的提问来源于stack exchange,提问作者noone392
相关产品推荐
相关产品推荐

