Angular 13向FastAPI上传文件时报422 Unprocessable Entity错误
Angular 上传文件到FastAPI返回422(缺少file字段)排查方案
错误提示loc: ['body', 'file'], msg: 'field required'明确表示后端无法从请求体中解析到你上传的文件字段,按以下优先级排查修复即可:
1. 修复FastAPI接口参数顺序问题
你当前的接口把Request参数放在了UploadFile参数前面,FastAPI的参数解析器会因此误判文件参数的来源位置,无法从multipart表单中提取文件。
把文件参数调整到Request之前即可:
@router.post('/v1/file') # 注意:UploadFile类型的文件参数必须放在Request参数前面 async def create_file(file: UploadFile = File(...), request: Request): # 你的业务逻辑 res = await file.read() return {"status": "success"}
2. 排查全局中间件是否提前消费了请求体
如果你配置了全局HTTP中间件做日志打印、签名校验之类的逻辑,且在中间件里调用了await request.body()读取请求内容,会导致后续路由处理函数无法再次读取请求体,自然拿不到上传的文件。
修复方式是读完请求体后把内容重新挂载回请求对象:
@app.middleware("http") async def process_request(request: Request, call_next): body = await request.body() # 这里写你自己的中间件逻辑,比如日志打印、签名校验 # 关键:把请求体重新放回receive方法,供下游路由读取 async def receive(): return {"type": "http.request", "body": body} request._receive = receive response = await call_next(request) return response
3. 排查Angular侧请求头配置错误
你当前写的FormData拼接逻辑本身没有问题,重点检查全局HttpInterceptor的配置:
- 不要手动给上传请求设置
Content-Type: multipart/form-data请求头,Angular会自动识别FormData对象,生成带正确boundary边界值的请求头,手动设置反而会因为缺少boundary导致后端解析失败 - 如果你的拦截器默认给所有请求加了
Content-Type: application/json头,要针对FormData类型的请求跳过这个设置:
intercept(req: HttpRequest<any>, next: HttpHandler) { // 仅对非FormData请求设置json头 if (!(req.body instanceof FormData)) { req = req.clone({ setHeaders: { 'Content-Type': 'application/json', // 其他全局请求头 } }) } return next.handle(req); }
以上三个问题覆盖了99%同场景的422报错,按顺序调整后即可正常上传文件。
内容的提问来源于stack exchange,提问作者Jane Wayne
相关产品推荐
相关产品推荐

