You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Axios发送POST请求时图片无法上传问题排查求助

解决FastAPI接收图片时的Unprocessable Entity与字段匹配问题

嘿,我来帮你一步步排查这个问题:

问题1:手动设置Content-Type导致的解析错误

你前端代码里手动指定了Content-Type: multipart/form-data,这其实是错误操作。当axios发送FormData类型的数据时,会自动生成正确的multipart/form-data请求头,并且会带上必要的boundary分隔符(用来区分不同的表单字段)。手动设置这个头会丢失boundary信息,导致后端无法正确解析文件,把上传的文件当成了字符串,这就是你看到Expected UploadFile, received: <class 'str'>错误的原因。

问题2:表单字段名与后端参数不匹配

你提到数据库字段是image_url,但FastAPI接收文件的参数名需要和前端FormData.append()的key完全一致,而不是直接对应数据库字段名:

  • 如果后端定义的接收文件的参数是files(比如files: List[UploadFile] = File(...)),那前端就要用data.append("files", file)
  • 如果后端参数是image_url(比如image_url: List[UploadFile] = File(...)),前端才需要用data.append("image_url", file)

字段名不匹配就会触发fields required错误,因为后端找不到对应的参数。

修正后的前端代码

把手动设置的Content-Type去掉,axios会自动处理:

let url = 'http://127.0.0.1:8000/post_ads';
// 移除Content-Type,其他头保留(注意如果是Bearer认证,Authorization应该是"Bearer xxx"格式)
let headers = { 'username': '', 'password': '', 'Authorization': '' };
var data = new FormData();
data.append('is_new_item', is_new);
// 这里的key要和后端接收文件的参数名一致
image.forEach(file=>{ data.append("files", file) })
let submit_ads = axios.post(url, data, {headers: headers}).then((res)=>{ 
    console.log(res) 
}).catch(err => {
    console.error(err.response.data); // 方便查看后端返回的详细错误
})

对应的后端示例(FastAPI)

确保后端的参数名和前端一致,比如:

from fastapi import FastAPI, File, UploadFile
from typing import List

app = FastAPI()

@app.post("/post_ads")
async def post_ads(is_new_item: str, files: List[UploadFile] = File(...)):
    # 这里处理文件,比如保存后把路径存到数据库的image_url字段
    return {"message": f"Received {len(files)} files"}

如果后端参数名是image_url,就改成:

async def post_ads(is_new_item: str, image_url: List[UploadFile] = File(...)):

这样调整后,应该就能正常上传图片啦~

内容的提问来源于stack exchange,提问作者boyenec

火山引擎 最新活动