FastAPI POST请求报错:参数不匹配与method对象不可下标问题排查
FastAPI POST请求报错问题排查
问题描述
向FastAPI后端发送POST请求时,先后触发两个错误:
- 初始无参数的
test函数报错:test() takes 0 positional arguments but 1 was given - 添加
request参数后,报错:TypeError: 'method' object is not subscriptable
前端代码
import requests data = {"foo": "bar"} r = requests.post("http://127.0.0.1:8000/test", json=data) print(r.text)
后端代码(出错版本)
import requests 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=["*"], ) @app.route('/test', methods=['POST']) def test(request): print(request.form['foo']) return 'thisIsResponse'
错误堆栈信息
Traceback (most recent call last): File "/usr/lib/python3/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi result = await app(self.scope, self.receive, self.send) File "/usr/lib/python3/dist-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__ return await self.app(scope, receive, send) File "/home/spree/.local/lib/python3.10/site-packages/fastapi/applications.py", line 271, in __call__ await super().__call__(scope, receive, send) File "/home/spree/.local/lib/python3.10/site-packages/starlette/applications.py", line 118, in __call__ await self.middleware_stack(scope, receive, send) File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__ raise exc File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__ await self.app(scope, receive, _send) File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/cors.py", line 84, in __call__ await self.app(scope, receive, send) File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__ raise exc File "/home/spree/.local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__ await self.app(scope, receive, sender) File "/home/spree/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__ raise e File "/home/spree/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__ await self.app(scope, receive, send) File "/home/spree/.local/lib/python3.10/site-packages/starlette/routing.py", line 706, in __call__ await route.handle(scope, receive, send) File "/home/spree/.local/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle await self.app(scope, receive, send) File "/home/spree/.local/lib/python3.10/site-packages/starlette/routing.py", line 66, in app response = await func(request) File "/home/spree/spreeTv/./ods_info.py", line 30, in test print(request.form['foo']) TypeError: 'method' object is not subscriptable
错误原因
- 第一个错误:使用
@app.route装饰器时,FastAPI(底层基于Starlette)会自动向路由函数传入Request对象作为参数,无参数的函数无法接收该参数,因此触发参数不匹配错误。 - 第二个错误:
request.form是异步方法,必须通过await调用才能获取表单数据,直接用下标访问会触发“方法不可下标”的错误;- 前端发送的是JSON格式数据(
Content-Type: application/json),而非表单编码数据,即使正确调用request.form()也无法获取到数据。
解决方法
方法一:FastAPI原生请求体解析(推荐)
利用FastAPI的Pydantic模型自动解析JSON请求体,代码更简洁且自带数据校验:
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 定义请求体结构模型 class RequestData(BaseModel): foo: str # 使用FastAPI专属的@app.post装饰器 @app.post('/test') def test(data: RequestData): print(data.foo) return 'thisIsResponse'
方法二:手动处理Request对象(特殊场景适用)
若需直接操作Request对象,需将函数定义为异步函数,并通过await request.json()获取JSON数据:
from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.post('/test') async def test(request: Request): json_data = await request.json() print(json_data['foo']) return 'thisIsResponse'
注意事项
- 前端代码无需修改,已正确使用
json=data发送JSON请求; - 优先使用方法一,FastAPI会自动生成API文档、数据校验等功能,符合框架设计规范。
内容的提问来源于stack exchange,提问作者seriously
相关产品推荐
相关产品推荐

