React上传文件至FastAPI报错:value is not a valid dict求助
文件上传功能错误分析与解决
错误场景
使用React + FastAPI开发文件上传功能时,前端发送请求后收到错误:
{loc: ["body"], msg: "value is not a valid dict", type: "type_error.dict"}
问题原因
- JSON无法序列化文件对象:前端用
JSON.stringify处理File对象时,会将其序列化为空结构,FastAPI接收后无法识别为有效的文件列表,导致解析失败。 - 请求格式与参数类型不匹配:文件上传必须使用
multipart/form-data格式,而当前前端发送的是JSON格式;同时FastAPI的UploadFile类型不能直接放在BaseModel中通过JSON Body接收,必须通过表单字段接收。
解决步骤
前端(React)修改
改用FormData构建请求体,这是浏览器处理文件上传的标准方式:
const handleUpload = async () => { try { const formData = new FormData(); // 逐个添加文件和对应的override参数 selectedFiles.forEach((file, index) => { formData.append('files', file); // 将布尔值转为字符串,因为FormData仅支持字符串/Blob类型 formData.append('override', selectedOveride[index].toString()); }); const resp = await fetch('/api/uploadfile/', { method: 'POST', body: formData // 无需手动设置Content-Type,浏览器自动添加正确的multipart/form-data头 }); const data = await resp.json(); console.log(data); // 后续状态更新逻辑... } catch (error) { console.error('Error:', error); setError('There was an error connecting to the host'); } };
后端(FastAPI)修改
调整接口参数,用File接收文件,Form接收override参数:
from fastapi import FastAPI, File, UploadFile, Form from typing import List app = FastAPI() @app.post("/api/uploadfile/") async def upload_files( files: List[UploadFile] = File(...), override: List[str] = Form(...) ): # 将字符串类型的override转为布尔值 override_bool = [val.lower() == 'true' for val in override] # 这里编写文件处理逻辑 return { "completed": [file.filename for file in files], "exists": [] }
如果希望用类统一管理参数,可以结合Pydantic模型和自定义表单依赖:
from fastapi import FastAPI, File, UploadFile, Form, Depends from pydantic import BaseModel from typing import List class UploadRequest(BaseModel): override: List[bool] @classmethod def as_form(cls, override: List[str] = Form(...)): return cls(override=[val.lower() == 'true' for val in override]) app = FastAPI() @app.post("/api/uploadfile/") async def upload_files( files: List[UploadFile] = File(...), request: UploadRequest = Depends(UploadRequest.as_form) ): # 使用request.override获取布尔列表 return { "completed": [file.filename for file in files], "exists": [] }
内容的提问来源于stack exchange,提问作者zacaaron
相关产品推荐
相关产品推荐

