客户代码:
!<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<form id="uploadForm" role="form" method="post" enctype=multipart/form-data>
<input type="file" id="file" name="file" multiple>
<input type=button value=Upload onclick="uploadFile()">
</form>
<script type="text/javascript">
function uploadFile() {
var formData = new FormData();
var imagefile = document.querySelector('#file');
formData.append("images", imagefile.files);
axios.post('http://127.0.0.1:8000/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
</script>
</body>
</html>
服务器代码:
from fastapi import FastAPI, File, UploadFile, FastAPI
from typing import Optional, List
from fastapi.responses import FileResponse, HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
...
def save_file(filename, data):
with open(filename, 'wb') as f:
f.write(data)
print('file saved')
@app.post("/upload")
async def upload(files: List[UploadFile] = File(...)):
print(files)
for file in files:
contents = await file.read()
save_file(file.filename, contents)
print('file received')
return {"Uploaded Filenames": [file.filename for file in files]}
出现以下错误:
←[32mINFO←[0m: 127.0.0.1:10406 - "←[1mPOST /upload HTTP/1.1←[0m" ←[31m400 Bad Request←[0m
我已经尝试通过表单操作上传一个文件,所有工作正常,但我需要上传两个文件。
2条答案
按热度按时间az31mfrm1#
首先,当上传文件或表单数据时,应该使用在端点/路由中定义的相同表单键。在您的情况下,该键是
files
。因此,在客户端应该使用该键而不是images
。其次,上载多个文件的方法是循环遍历文件数组(即代码中的
imagefile.files
),并将每个文件添加到FormData
对象。第三,错误似乎是由于Axios的
0.27.1
版本中的一些bug/更改而发生的。这里是最新的related issue on GitHub。使用cdnjs here的最新版本,即0.27.2
解决了这个问题。或者,您可以使用Fetch API,类似于this answer(您可以使用与下面Axios示例相同的方式添加文件列表)。在Fetch API中,当将文件上传到服务器时,您不应该显式设置请求上的
Content-Type
头,如here所述。工作示例(使用Axios)
ih99xse12#
从Axios v 0.27.2开始,您可以轻松地完成此操作:
所有文件将使用
files[]
密钥提交。更详细的示例: