FastAPI实现文件上传下载
最近的项目需求,是前端vue,后端fastAPI,然后涉及到图像的消息发送,所以需要用fast写文件上传下载的接口,这里简单记录一下。
1.后端FastAPI
python
import os.path
import uvicorn
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(# 解决跨域问题
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
#@app.get("/")#测试接口
#async def hello():
# return {"ret": 'hello'}
@app.post("/uploadfile/")#前端上传的文件会放在文件目录下的uploaded_files目录下
async def create_upload_file(file: UploadFile = File(...)):
print(file)
if not os.path.exists('uploaded_files'):
os.mkdir('uploaded_files')
with open(f"uploaded_files/{file.filename}", "wb") as f:
f.write(await file.read())
return {"filename": file.filename}
@app.get("/downloadfile/{filename}")#前端会传递一个文件名,然后从后端文件目录的downloadfile目录下找到这个文件去下载
async def download_file(filename: str):
directory_path = f"{os.path.dirname(__file__)}/downloadfile/"
file_path = os.path.join(directory_path, filename)
print(file_path)
return FileResponse(file_path, media_type="application/octet-stream", filename=filename)
if __name__ == '__main__':
uvicorn.run('upload:app', host='127.0.0.1', port=18005, reload=False)
2.后端html
我用postman测试后端没问题后,用html搞了一个简单的前端,实现这个功能,这里从后端下载文件到前端时需要前端给一个文件名,这个文件名一定要是后端/downloadfile/文件夹下的文件名,否则下载不到文件。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传与下载</title>
</head>
<body>
<h1>文件上传与下载d</h1>
<!-- 文件上传表单 -->
<form id="uploadForm" enctype="multipart/form-data">
<input type="file" id="fileInput" name="file" accept=".txt">
<button type="button" onclick="uploadFile()">上传</button>
</form>
<!-- 文件下载按钮 -->
<input type="text" id="fileNameInput" placeholder="输入后端downloadfile文件夹下的文件名">
<button onclick="downloadFile()">下载</button>
<script>
async function uploadFile() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
if (file) {
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch('http://127.0.0.1:18005/uploadfile/', {
method: 'POST',
body: formData
});
if (response.ok) {
alert('文件上传到后端upload_files目录下成功!');
} else {
alert('文件上传失败.');
}
} catch (error) {
console.error(error);
alert('文件上传失.');
}
} else {
alert('请选择需要上传的文件.');
}
}
async function downloadFile() {
// 获取输入框中的文件名
const fileName = document.getElementById("fileNameInput").value;
try {
// 使用 fetch 请求下载文件
const response = await fetch(`http://127.0.0.1:18005/downloadfile/${fileName}`);
if (response.ok) {
// 将文件转换为 Blob
const blob = await response.blob();
// 创建一个链接并设置下载属性
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
// 模拟点击下载链接
link.click();
} else {
alert('从后端downloadfile目录里下载此文件失败.');
}
} catch (error) {
console.error(error);
alert('下载文件出错.');
}
}
</script>
</body>
</html>