使用SolidJS+Axios对接FastAPI时遭遇浏览器CORS跨域问题
从你的响应头可以看出,后端返回的结果缺少Access-Control-Allow-Origin字段——这是浏览器触发CORS拦截的核心原因,尽管接口返回了200状态码,但浏览器会因为缺少这个必要的CORS响应头而拒绝将结果返回给前端。
下面是针对性的排查和修复方案:
1. 确认CORS中间件的注册顺序
FastAPI的中间件按注册顺序生效,必须确保CORSMiddleware在所有路由(包括通过include_router添加的路由)之前注册。检查你的代码结构,确保如下顺序:
app = FastAPI() origins = [ 'http://localhost:3000' ] # 先注册CORS中间件 app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=['*'], allow_headers=['*'], ) # 再添加路由 app.include_router(users.router)
如果路由注册在中间件之前,可能导致路由请求无法被CORS中间件处理,从而缺失响应头。
2. 排查路由或自定义中间件对响应头的覆盖
检查users.router或login路由中是否有手动修改响应头的代码,比如:
from fastapi import Response @router.post('/login', response_model=CustomModel) async def login(token, request: Request = None, response: Response = None): # 此类代码可能覆盖或删除CORS相关响应头 response.headers.clear() response.headers["Content-Type"] = "application/json" return response
如果存在类似操作,会导致CORSMiddleware添加的Access-Control-Allow-Origin等头被移除,需要避免直接清空所有响应头,或手动保留CORS相关字段。
3. 测试基础路由的CORS响应
在主app中添加一个简单的测试路由,排除路由本身的问题:
@app.get("/test-cors") async def test_cors(): return {"msg": "cors test"}
用前端请求http://localhost:8000/test-cors,查看响应头是否包含Access-Control-Allow-Origin: http://localhost:3000:
- 如果有:说明问题出在
users.router的配置上,检查路由是否有自定义中间件或特殊处理 - 如果没有:说明CORSMiddleware根本未生效,需要检查依赖版本或启动方式
4. 更新依赖库版本
旧版本的fastapi或starlette(CORSMiddleware来自starlette)可能存在bug,执行以下命令更新:
pip install --upgrade fastapi starlette uvicorn
5. 前端代码的正确配置
无需手动添加crossDomain或Access-Control-Allow-Origin请求头(后者是后端返回的字段,前端添加会触发浏览器拦截)。当后端设置allow_credentials=True时,前端只需确保withCredentials: true:
axios({ method: 'post', url: 'http://localhost:8000/login', headers: { Accept: 'application/json' }, params: { token: 'RANDOM_TOKEN_VALUE', }, withCredentials: true }).then((response) => { console.log(response) });
内容的提问来源于stack exchange,提问作者S. Yong

