前后端分离时代,端口、域名、协议只要有一项不同,就会触发浏览器的「同源策略」拦截。
FastAPI 原生自带
CORSMiddleware
,只需几行代码即可让你的 API 被任意前端「安全」调用。本文带你从原理到生产,一次搞定跨域配置。
一、跨域问题的根因:浏览器的同源策略
同源 = 协议 + 域名 + 端口 完全一致
只要三者任一不同,浏览器就会先发一次 预检(OPTIONS)请求 ,再决定是否放行真正的业务请求。
如果服务器未返回正确的 CORS 响应头,请求会被浏览器静默拦截,前端收不到任何数据。
二、FastAPI 的解决思路:官方 CORS 中间件
FastAPI 直接集成了 Starlette 的 CORSMiddleware
,无需额外安装第三方包。
核心方法:在 FastAPI()
实例上注册中间件,指定允许的来源、方法、头部、凭证等参数即可 。
三、最小可运行示例(开发环境秒开)
python
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware # ① 导入
app = FastAPI()
# ② 添加中间件
app.add_middleware(
CORSMiddleware,
allow_origins=["*], # 开发阶段放通所有
allow_credentials=True, # 需要 Cookie/Authorization 时设为 True
allow_methods=["*"], # 允许全部 HTTP 方法
allow_headers=["*"], # 允许全部请求头
)
@app.get("/api/hello")
async def hello():
return {"msg": "跨域请求成功"}
启动:
bash
uvicorn main:app --reload
前端(http://localhost:3000)可直接 fetch("http://localhost:8000/api/hello")
,浏览器不再报 CORS 错误 。
四、生产环境:别再用 "*"
!精细化配置示例
python
origins = [
"https://app.example.com", # 正式域名
"https://admin.example.com",
"http://localhost:3000", # 本地开发
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True, # 允许携带 Cookie/Session
allow_methods=["GET", "POST", "PUT", "DELETE"], # 按需开放
allow_headers=["Content-Type", "Authorization", "X-Requested-With"],
max_age=86400, # 预检缓存 24h,减少 OPTIONS 次数
)
要点说明
allow_credentials=True
时allow_origins
不能是["*"]
,必须显式列表。max_age
可让浏览器缓存预检结果,提升性能。- 若使用 HTTPS ,前端地址也必须是
https://
,否则浏览器仍拦截。
五、与 Nginx 反向代理的配合(可选)
如果已用 Nginx 统一入口,可在 Nginx 层返回 CORS 头,后端保持关闭 CORS:
nginx
location /api {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
add_header Access-Control-Allow-Headers Content-Type,Authorization;
if ($request_method = OPTIONS) { return 204; } # 预检快速返回
proxy_pass http://fastapi:8000;
}
优势 :减少后端压力;缺点:多一层配置,需要运维配合。
六、常见报错速查表
前端报错 | 原因 | 解决 |
---|---|---|
CORS header 'Access-Control-Allow-Origin' missing |
未加中间件或 allow_origins 写错 |
检查 add_middleware 是否注册 |
The value of the 'Access-Control-Allow-Origin' header must not be the wildcard * when credentials are true |
allow_credentials=True 却用 "*" |
把 allow_origins 改成具体列表 |
Request header field x-custom-header is not allowed |
不在 allow_headers 白名单 |
追加自定义 header |
OPTIONS 405 Method Not Allowed |
预检被后端路由拦截 | 确保 allow_methods=["*"] 或包含 OPTIONS |
七、总结:三步口诀
- 开发 :
allow_origins=["*"]
先跑通 - 测试 :逐项收紧,显式域名 + 最小方法 + 最小头部
- 上线 :
credentials=True
务必配具体域名,拒绝"*"
记住:CORS 配置不是越多越好,而是越精准越安全。
照着本文模板,10 分钟即可让你的 FastAPI 服务与前端「跨域无阻碍」联调上线 。