向FastAPI发送JSON字符串遇422错误,Fetch失效Axios正常
FastAPI接口Fetch请求返回422错误排查
向FastAPI接口发送指定JSON字符串时,Fetch请求始终返回422错误,但Postman和Axios请求可正常成功。
发送的JSON内容
{"data":[{"pickup_session_id":1,"product_id":3,"product_usage_type_id":0,"total":0},{"pickup_session_id":1,"product_id":3,"product_usage_type_id":25,"total":0},{"pickup_session_id":1,"product_id":3,"product_usage_type_id":50,"total":0},{"pickup_session_id":1,"product_id":3,"product_usage_type_id":75,"total":0},{"pickup_session_id":1,"product_id":3,"product_usage_type_id":100,"total":0},{"pickup_session_id":1,"product_id":8,"product_usage_type_id":0,"total":0},{"pickup_session_id":1,"product_id":8,"product_usage_type_id":25,"total":0},{"pickup_session_id":1,"product_id":8,"product_usage_type_id":50,"total":0},{"pickup_session_id":1,"product_id":8,"product_usage_type_id":75,"total":0},{"pickup_session_id":1,"product_id":8,"product_usage_type_id":100,"total":0}]}
失败的Fetch请求代码
const x = JSON.stringify(obj) console.log(x); const response = await fetch(`http://localhost:8000/pickups/`, { method: "POST", mode: "no-cors", headers: { Accept: "application/json", "Content-Type": "application/json;charset=UTF-8", }, body: x });
成功的Axios请求代码
obj['data'] = d; const x = JSON.stringify(obj) console.log(x); axios.post(`http://localhost:8000/pickups/`, obj, { headers: { 'Access-Control-Allow-Origin': '*', Accept: "application/json", "Content-Type": "application/json;charset=UTF-8", }, }) .then(({data}) => { alert(data); console.log(data); });
服务端FastAPI代码
@router.post('/') async def create_pickup(pickupSchemaList: PickupInList, session = Depends(get_session)): #async def create_pickup(request: Request, session = Depends(get_session)): #print(await request.json()) async with session() as session: for pickup_schema in pickupSchemaList.data: print(pickup_schema) pickup = Pickup( pickup_session_id=pickup_schema.pickup_session_id, product_id=pickup_schema.product_id, product_usage_type_id=pickup_schema.product_usage_type_id, total=pickup_schema.total ) session.add(pickup) await session.commit() await session.refresh(pickup)
Pydantic模型定义
class PickupIn(BaseModel): pickup_session_id: int product_id: int product_usage_type_id: int total: int class PickupInList(BaseModel): data: list[PickupIn]
问题原因及解决办法
核心问题在于Fetch请求中的mode: "no-cors"配置:
当启用no-cors模式时,浏览器会强制限制请求头的发送,即便你显式设置了Content-Type: application/json,浏览器也不会实际传递这个头部信息。FastAPI无法识别请求体的JSON格式,因此返回422验证错误。而Axios请求未设置该模式,浏览器能正常发送所有指定请求头,FastAPI可正确解析请求体。
解决步骤
- 移除Fetch请求中的
mode: "no-cors"配置 - 服务端配置CORS中间件:确保FastAPI允许前端域名的跨域请求,示例配置如下:
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() # 替换为你的前端实际域名 origins = [ "http://localhost:3000", "http://127.0.0.1:3000", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
内容的提问来源于stack exchange,提问作者Ruben
相关产品推荐
相关产品推荐

