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

Dart可正常运行的HTTP请求在Flutter中触发XMLHttpRequest错误

问题原因与解决办法

为什么纯Dart正常,Flutter里报错?

  • 纯Dart脚本运行在命令行环境,没有浏览器的跨域安全限制,直接发送HTTP请求不会被拦截。
  • 当你在Flutter中运行(尤其是Flutter Web),代码会在浏览器环境执行,浏览器的同源策略会阻止跨域的HTTP请求(你的前端页面和Python服务器域名/端口不一致,属于跨域场景),因此会抛出XMLHttpRequest相关错误。即使是Flutter移动端,默认也会限制HTTP明文请求,优先要求HTTPS,但纯Dart命令行不存在这个限制。

解决办法

1. 给Python HTTP服务器添加CORS支持

修改Python服务器代码,在响应中加入CORS允许的请求头,让浏览器放行跨域请求。可以编写自定义的HTTP请求处理器:

from http.server import BaseHTTPRequestHandler, HTTPServer

class CORSRequestHandler(BaseHTTPRequestHandler):
    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()

    def do_POST(self):
        # 保留原有POST处理逻辑
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b"Received POST data: " + post_data)

if __name__ == '__main__':
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, CORSRequestHandler)
    print('Starting server on port 8000...')
    httpd.serve_forever()

运行这个自定义服务器后,Flutter的请求就能正常被处理。

2. Flutter移动端允许HTTP明文请求

如果是在Flutter Android/iOS移动端运行,默认禁止HTTP明文请求,需要手动配置允许:

  • Android:在android/app/src/main/AndroidManifest.xml的application标签中添加android:usesCleartextTraffic="true"
  • iOS:在ios/Runner/Info.plist中添加以下配置:
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    

3. 改用HTTPS(生产环境推荐)

生产环境建议配置HTTPS,避免明文传输的安全风险。可以用工具生成自签名证书,然后让Python服务器支持HTTPS,示例代码如下:

import ssl
from http.server import HTTPServer, BaseHTTPRequestHandler

server_address = ('', 8443)
httpd = HTTPServer(server_address, BaseHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket,
                               server_side=True,
                               certfile='server.crt',
                               keyfile='server.key',
                               ssl_version=ssl.PROTOCOL_TLS)
print('Starting HTTPS server on port 8443...')
httpd.serve_forever()

之后Flutter请求改用Uri.https访问即可。

内容的提问来源于stack exchange,提问作者Jeremy Parker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:12:58