FastAPI实现文件上传下载
- 1.后端FastAPI
- 2.后端html
- 3.效果
最近的项目需求,是前端vue,后端fastAPI,然后涉及到图像的消息发送,所以需要用fast写文件上传下载的接口,这里简单记录一下。
1.后端FastAPI
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/文件夹下的文件名,否则下载不到文件。
<!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) {// 将文件转换为 Blobconst 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>