本文的上一篇是 Vue+Fastapi 上传文件的简单示例 ,因为这篇文章是单文件上传,但是很多情况下需要传输多个文件,所以多文件上传也是必不可少的。
1 思路
分为前端和后端,前端使用Vue,后端采用FastaApi
2 实现
2.1 多文件上传后端
接受前端传来的文件,可以是单文件也可以是多文件,返回上传的文件名来判断是否真正的上传完成
from typing import List #重要
from fastapi import FastAPI, File, UploadFile
app = FastAPI()@app.post(“/files/”)
async def create_files(files: List[bytes] = File(…)):
rt_data = {“path”:[]}
for file in files:
file_data = await file.read()
name = save_file(file_data,file.filename,[Your file path])
rt_data[“path”].append(name)
return {“file_sizes”: [len(file) for file in files]}@app.post(“/uploadfiles/”)
async def create_upload_files(files: List[UploadFile] = File(…)):
rt_data = {“path”:[]}
for file in files:
file_data = await file.read()
name = save_file(file_data,file.filename,[Your file path])
rt_data[“path”].append(name)
return {“filenames”: [file.filename for file in files]}#这个实现方法和单文件上传唯一区别就是引入了typing模块的List, 该模块仅支持3.5以上版本,作用是进行类型注解。
#下面这个函数用来保存文件
def save_file(filedata,filename,path):
with open(path + filename,”wb”) as fp:
fp.write(filedata)
fp.close()
return filename
2.2 文件上传前端
实现办法:创建一个文件选择的Input 同时将其设置为不可见,创建两个按钮,一个代替选择,一个代替上传,首先从原生的input内获取选择的文件列表,保存在data内,使用axios上传时循环将文件append到需要上传的FromData内。具体代码可以参考如下:
<!DOCTYPE html><html><head><meta charset=”UTF-8″><link rel=”stylesheet” href=”https://unpkg.com/element-ui/lib/theme-chalk/index.css”></head><body><div id=”app”><el-button @click=”addFile”>addFile</el-button><el-button @click=”uploadFile”>uploadFile</el-button><input type=”file” ref=”upload_input” multiple style=”display: none;” @change=”select_file”></div></body><script src=”https://unpkg.com/vue/dist/vue.js”></script><script src=”https://unpkg.com/element-ui/lib/index.js”></script><script src=”https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js”></script><script>new Vue({el: ‘#app’,data: function () {return {select_file_data: [],target_url: ”}},methods: {addFile: function () {this.$refs.upload_input.click()},uploadFile: function () {let uploads = new FormData()let config = { headers: { “Content-Type”: “multipart/form-data” } }if (this.select_file_data != []) {for (let i = 0; i < this.select_file_data.length; i++) {uploads.append({ “files“: this.select_file_data[i]})}axios.post(this.target_url, uploads, config).then(function (res) {console.log(res.data)})}},select_file: function (file) {this.select_file_data = file.target.filesconsole.log(this.select_file_data)}}})</script></html>