FastAPI接收application/x-www-form-urlencoded POST请求时出现422错误求助
FastAPI无法通过Pydantic或Body解析application/x-www-form-urlencoded类型POST数据
我在使用FastAPI开发接口时,尝试通过Pydantic模型或FastAPI的Body对象获取POST请求数据,但始终失败。以下是我的代码:
from fastapi import Request, FastAPI from fastapi.params import Body app = FastAPI() @app.post('/messagebird/flow_v2') async def messagebird_flow(request: Request, payload: dict = Body(...)): body = await request.body() # 这种方式可行,但我不想用 print(payload) # 这里完全取不到数据
运行后会返回422错误:
INFO: 127.0.0.1:59870 - "POST /messagebird/flow_v2 HTTP/1.1" 422 Unprocessable Entity
请求的具体信息如下(Content-Type为application/x-www-form-urlencoded):
POST /messagebird/flow_v2 HTTP/1.1 Host: 2d40-83-43-203-143.eu.ngrok.io User-Agent: MessageBird Flows API/2.0 Content-Length: 616 Accept-Encoding: gzip Content-Type: application/x-www-form-urlencoded Messagebird-Request-Timestamp: 1669666185 Messagebird-Signature: PVShU4B/UrrhcK5jnEzYBYtwOy7NdDkYvviqEPs+Pmo= Messagebird-Signature-Jwt: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTY2OTY2NjE4NSwiZXhwIjoxNjY5NjY2MjQ1LCJqdGkiOiIwOWQyOWQ5YS0zZDM1LTQyYjktYTI3OS05ODQ1NTIzZWY0N2YiLCJ1cmxfaGFzaCI6IjRlOGVhMzM5ODUxNmZiYjE5MTg2MWFlMzgyYTdiNjc1ODAyMzVkNjUwNDIzZmFiNDE2Mjg0NGNkY2RmMTgzZDMiLCJwYXlsb2FkX2hhc2giOiJiNTUwNTlhMDA1OWU3ZDc5NjU5MDljOWIzNjM4NDI4Njk5ZDFjNzdhNDcyNzIxODVkMTgyNDgwYWUxOGFiNzkwIn0.tcmw9i0-UcNilXjCfixzJnp7m4JX9k2YzMDBFczyG_o X-Forwarded-For: 34.90.201.190 X-Forwarded-Proto: https agent=Luc%C3%ADa&channelId=6b413a63-46be-4dbc-bad6-d5a2ed28499a&company=COMPANY&conversationId=1068fe69521b46f6b179dc982f3acda3&flowId=a9343b4e-859a-44af-81b2-ffb17d8f8c45&flowRevisionId=f45ed841-a629-4891-b813-a4f29da68d6a&from=6b413a63-46be-4dbc-bad6-d5a2ed28499a&invocationId=54fb2d37-09ce-4db8-9bef-ded0299d8238&lastConversationId=1068fe69521b46f6b179dc982f3acda3&lastMessageSentId=bde39e8661ef44f9a7ed6ee0ca4d2593&lastMessageSentTo=34660049970&messageBirdRequestId=93ba7f30-6f58-11ed-b3a3-2e5ef0e7161f&problem=PROBLEM&sleep=5+seconds&solution=SOLUTION&to=%2B34660049970&uuid=bie594NFWQVstFWWvziieU&wait=24+hours
我已经尝试过的方法:
- 使用Pydantic模型绑定请求数据
- 使用
fastapi.params.Body对象接收数据
但这两种方式都无法解决问题。
解决方案
问题根源在于:FastAPI的Body(...)默认仅支持解析application/json类型的请求体,而当前请求的Content-Type是application/x-www-form-urlencoded(表单格式),因此无法自动解析导致422错误。
方法一:用Pydantic模型结合Form参数(推荐,支持数据校验)
通过Form参数逐个接收字段,再映射到Pydantic模型中,既可以享受数据校验的优势,又能正确解析表单数据:
from fastapi import FastAPI, Form, Depends from pydantic import BaseModel app = FastAPI() # 根据请求字段定义Pydantic模型 class FlowPayload(BaseModel): agent: str channelId: str company: str conversationId: str flowId: str # 其他字段根据实际请求补充完整 # 定义依赖函数,将Form参数转换为Pydantic模型 def parse_form_data( agent: str = Form(...), channelId: str = Form(...), company: str = Form(...), conversationId: str = Form(...), flowId: str = Form(...), # 其他字段依次定义 ) -> FlowPayload: return FlowPayload( agent=agent, channelId=channelId, company=company, conversationId=conversationId, flowId=flowId, # 对应赋值其他字段 ) @app.post('/messagebird/flow_v2') async def messagebird_flow(payload: FlowPayload = Depends(parse_form_data)): print(payload.dict()) return {"status": "success", "data": payload.dict()}
方法二:直接获取表单数据转为字典(快捷,无严格校验)
如果不需要数据校验,可直接通过request.form()方法获取所有表单数据并转为字典:
from fastapi import Request, FastAPI app = FastAPI() @app.post('/messagebird/flow_v2') async def messagebird_flow(request: Request): form_data = await request.form() payload = dict(form_data) print(payload) return {"status": "success", "data": payload}
内容的提问来源于stack exchange,提问作者tarco
相关产品推荐
相关产品推荐

