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.
问题排查与修复方案
- 移除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); } }
- 修复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()
- 额外注意点
- 如果是Flutter Web环境,尝试把
localhost换成127.0.0.1,部分浏览器对localhost的跨域处理有差异。 - 确保Python服务器和Flutter应用在同一网络环境下(本地运行则无需额外配置),端口8000未被其他程序占用。
- 打开浏览器控制台的Network标签,查看OPTIONS预检请求的响应状态和返回头,确认CORS头是否正确返回。
内容的提问来源于stack exchange,提问作者Abdullah Attiq
相关产品推荐
相关产品推荐

