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

Flutter Web无法访问FastAPI接口:跨域请求被拦截求助

解决方案

1. 核心问题:浏览器无法访问Docker内部IP

浏览器运行在用户本地环境,无法直接访问服务器上的Docker内网IP(172.21.0.2),这才是请求失败的根本原因,CORS错误只是表象。你需要通过服务器公网IP/域名来访问FastAPI,而非容器内部IP。

2. 统一用HTTPS对外提供服务

因为Flutter Web使用HTTPS,浏览器会严格阻止混合内容请求(HTTPS页面发起HTTP请求),所以必须让FastAPI也通过HTTPS对外暴露,推荐两种实现方式:

方式一:用Nginx反向代理统一处理(首选)

和Flutter Web共用Nginx,通过域名前缀区分请求,同时统一管理HTTPS证书。示例Nginx配置:

server {
    listen 443 ssl;
    server_name your-domain.com; # 替换为你的实际域名

    ssl_certificate /path/to/your.crt;
    ssl_certificate_key /path/to/your.key;

    # 转发Flutter Web请求
    location / {
        proxy_pass http://flutter-container:80; # 替换为Flutter容器的名称+端口(同一Docker网络可直接用容器名)
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 转发FastAPI请求,用/api前缀区分
    location /api/ {
        proxy_pass http://fastapi-container:8070/; # 替换为FastAPI容器的名称+端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

配置完成后,Flutter Web只需请求https://your-domain.com/api/xxx即可调用接口,无需再使用容器内部IP。

方式二:直接给FastAPI配置HTTPS

在FastAPI启动时通过uvicorn指定证书,示例启动命令:

uvicorn main:app --host 0.0.0.0 --port 8070 --ssl-keyfile=/path/to/your.key --ssl-certfile=/path/to/your.crt

然后将服务器的某个端口(如8443)映射到FastAPI容器的8070端口,Flutter Web通过https://your-server-ip:8443访问接口。这种方式需要在容器内挂载证书文件,不如Nginx统一管理便捷。

3. 验证FastAPI的CORS配置

确保FastAPI的CORS中间件正确初始化,示例代码:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

如果使用Nginx反向代理,也可以在Nginx中配置CORS规则,两种方式任选其一即可。

4. 测试连通性

修改配置后,先在服务器本地用curl验证FastAPI接口是否正常响应:

curl https://your-domain.com/api/your-endpoint

确认接口能正常返回数据后,再修改Flutter Web的请求地址并重新部署测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:17:21