在一个FastAPI接口,业务从Python3.8升级至Python3.11(镜像中的FastAPI框架从0.63升级到0.88)后,有一个处理客户端发来的请求时发现报错 ('body',):value is not a valid dict。本文地址:http://www.04007.cn/article/1249.html,未经许可,不得转载.
经过初步排查发现,客户端请求服务器端时使用的 Content-Type 是 application/x-www-form-urlencoded,服务端使用的是 BaseModel 模型接收,模型类中的属性使用的是 Query 来接收参数,在原版本(FastAPI框架0.63)时是可以接收的,但是换到新版本(FastAPI框架0.88)则会报错 ('body',):value is not a valid dict。这个错误是在框架层就通过 RequestValidationError 异常捕获的。可见这是较新版本的FastAPI框架0.88版中的不兼容导致,因为使用旧版本客户端既可以application/json,也可以使用application/x-www-form-urlencoded(此时发送仍是json数据格式) 正常接收。本文地址:http://www.04007.cn/article/1249.html,未经许可,不得转载.
首先还是推荐使用 application/json ,保持一致性,但现阶段客户端版本还是使用的application/x-www-form-urlencoded,只能考虑使用一种兼容 application/x-www-form-urlencoded 和 application/json 的方式来接收数据,尝试了多种方法,看来想通过框架层的Query、Body、Form等来直接兼容(不用作修改)是没有什么好办法,针对这个接口我就只能考虑做单独处理,在服务端器对统一接收到的原始数据进行自定义处理,不依赖原有的BaseModel类模型,使用 FastAPI 的 Body 获取原始post数据,通过对body数据类型进行区分来实现单独处理。本文地址:http://www.04007.cn/article/1249.html,未经许可,不得转载.
具体方法:通过 Body(...) 提取到body数据,如果接收到的body数据是bytes类型,则说明是通过 application/x-www-form-urlencoded 发送来的(带的json串),通过不是 bytes类型,则是通过 application/json 发送而来的(我这就只需要考虑这两种情况),此时数据格式是字典格式,不需要处理直接使用。然后再加上自己的参数校验即可。最后得到的info 即是一个包括参数字值的 dict 数据。代码如下:本文地址:http://www.04007.cn/article/1249.html,未经许可,不得转载.
from fastapi import APIRouter, Depends, Body @router.post("/test") async def login_test( body_string = Body(...) ) # 如果接收到的body是bytes类型,则说明是通过 application/x-www-form-urlencoded 发送 if isinstance(bodyc, bytes): info = json.loads(bodyc.decode()) else: info = bodyc #info 即是一个包括参数字值的 dict 数据。本文地址:http://www.04007.cn/article/1249.html,未经许可,不得转载.
本文地址:http://www.04007.cn/article/1249.html 未经许可,不得转载. 手机访问本页请扫描右下方二维码.
![]() |
![]() |
手机扫码直接打开本页面 |