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

Flutter调用Python后端遭遇XMLHTTPRequest CORS错误求助

Flutter调用Python后端接口遇XMLHTTPRequest错误(CORS问题未解决)

我正在开发一个Flutter示例应用,调用Python后端接口时,每次请求都会收到XMLHTTPRequest错误。已经尝试在Flutter和Python代码中添加CORS相关请求头,但问题仍未解决,恳请技术人士协助。

我的Flutter代码

Future<void> fetchSubjects() async {
    var url = Uri.parse('http://localhost:8000/subjects');
    try {
      final response = await http.get(
        url,
        headers: {
          "Access-Control-Allow-Origin": "*",
          "Access-Control-Allow-Headers":
              "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers",
        },
      );
      // 后续处理逻辑省略
    } catch (e) {
      print(e);
    }
}

我的Python代码

from http.server import BaseHTTPRequestHandler, HTTPServer

class S (BaseHTTPRequestHandler):
    def do_OPTIONS(self):
        print("OPTIONS request received")
        # Handle preflight requests
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        self.send_header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers")
        self.end_headers()
        
    def do_GET(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'Hello, World!')

def run(server_class=HTTPServer, handler_class=S, port=8000):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    # 服务器未启动时调用请求会直接报错,需删除此行
    # fetchSubjects()
    print(f'Starting server on port {port}...')
    httpd.serve_forever()
if __name__ == '__main__':
    run()

错误信息

运行上述代码后收到错误:XMLHttpRequest error.


问题排查与修复方案

  1. 移除Flutter请求中多余的CORS头
    Access-Control-Allow-Origin是后端返回给前端的响应头,不是前端请求头,在Flutter请求里添加这些头完全无效,反而可能引发问题,直接删除即可:
Future<void> fetchSubjects() async {
    var url = Uri.parse('http://localhost:8000/subjects');
    try {
      final response = await http.get(url);
      if (response.statusCode == 200) {
        // 处理成功响应
        print(response.body);
      }
    } catch (e) {
      print(e);
    }
}
  1. 修复Python后端的CORS逻辑
  • 响应头顺序错误:do_GET中必须先调用send_response发送状态码,再调用send_header设置响应头,否则头不会生效。
  • 重复设置响应头:do_OPTIONS中重复定义了Access-Control-Allow-Headers,保留完整的那一项即可。
  • 服务器启动前调用请求:run函数里的fetchSubjects()会在服务器启动前执行,此时后端还未运行,必然报错,必须删除这行。
  • 路径匹配(可选):给do_GET添加路径判断,确保只有访问/subjects时返回对应数据。

修改后的Python代码:

from http.server import BaseHTTPRequestHandler, HTTPServer

class S(BaseHTTPRequestHandler):
    def do_OPTIONS(self):
        print("OPTIONS请求已接收")
        # 处理预检请求
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers')
        self.end_headers()
           
    def do_GET(self):
        # 先发送状态码,再设置响应头
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Content-Type', 'application/json')  # 返回JSON时建议添加
        self.end_headers()
        
        # 匹配/subjects路径返回对应数据
        if self.path == '/subjects':
            self.wfile.write(b'{"subjects": ["数学", "英语", "物理"]}')
        else:
            self.wfile.write(b'Hello, World!')

def run(server_class=HTTPServer, handler_class=S, port=8000):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    print(f'服务器已启动,端口:{port}...')
    httpd.serve_forever()

if __name__ == '__main__':
    run()
  1. 额外注意点
  • 如果是Flutter Web环境,尝试把localhost换成127.0.0.1,部分浏览器对localhost的跨域处理有差异。
  • 确保Python服务器和Flutter应用在同一网络环境下(本地运行则无需额外配置),端口8000未被其他程序占用。
  • 打开浏览器控制台的Network标签,查看OPTIONS预检请求的响应状态和返回头,确认CORS头是否正确返回。

内容的提问来源于stack exchange,提问作者Abdullah Attiq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:18:12