使用Python aiohttp发送文件报“There was an error parsing the body”错误如何解决
错误原因
- 核心问题是你手动指定了
Content-Type: multipart/form-data请求头:multipart类型的表单请求必须携带boundary分隔符参数,该参数由aiohttp在构造请求时自动生成,手动写死请求头会覆盖掉带boundary的正确头,导致FastAPI无法拆分解析表单内容,抛出body解析错误。 - 额外优化点:传文件场景建议直接使用aiohttp提供的
FormData构造表单,兼容性更好。
修复后的代码
本地文件上传场景(对应你当前的示例)
from fastapi import FastAPI import aiohttp from aiohttp import FormData app = FastAPI() @app.post("/upload_client") async def async_call(): async with aiohttp.ClientSession() as session: # 移除手动设置的Content-Type头,由aiohttp自动生成 headers = {'accept': '*/*'} form = FormData() # 用with语法打开文件,避免文件句柄泄漏 with open("any_file", "rb") as f: form.add_field("file", f, filename="any_file") async with session.post("http://localhost:8000/upload", headers=headers, data=form) as response: return await response.json()
转发用户上传文件场景(对应你的实际需求)
你需要做的是用户上传到对外服务,再转发到内部服务,不需要存本地,可直接读取上传的文件流转发:
from fastapi import FastAPI, UploadFile, File import aiohttp from aiohttp import FormData app = FastAPI() @app.post("/upload_client") async def async_call(file: UploadFile = File(...)): async with aiohttp.ClientSession() as session: headers = {'accept': '*/*'} form = FormData() # 直接读取用户上传的文件内容转发 form.add_field("file", await file.read(), filename=file.filename) async with session.post("http://localhost:8000/upload", headers=headers, data=form) as response: return await response.json()
服务端补充优化
为了避免客户端解析返回值报错,可给服务端接口添加返回值:
from fastapi import FastAPI from fastapi import UploadFile, File app = FastAPI() @app.post("/upload") async def transcript_file(file: UploadFile = File(...)): return {"filename": file.filename, "status": "upload success"}
内容的提问来源于stack exchange,提问作者Hosten
相关产品推荐
相关产品推荐

