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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 16:44:55