在Web应用开发中,很多场景需要用户先通过POST请求提交参数,服务端根据参数生成或筛选对应文件再返回给用户下载,FastAPI作为轻量高效的Python Web框架,能够很方便地实现这一完整流程。

核心实现原理
FastAPI处理POST请求后下载文件的核心逻辑分为三步:首先接收POST请求携带的参数,然后根据参数执行文件生成或查询逻辑,最后通过StreamingResponse将文件内容作为响应返回,同时设置正确的响应头告知浏览器这是需要下载的文件。
基础实现步骤
1. 环境准备
首先需要安装FastAPI和uvicorn服务器,执行以下命令完成安装:
pip install fastapi uvicorn
2. 接收POST请求参数
我们可以通过Form或者Body接收POST请求携带的参数,以下示例接收用户提交的文件名参数:
from fastapi import FastAPI, Form
from fastapi.responses import StreamingResponse
import os
app = FastAPI()
# 假设本地有一个存放文件的目录
FILE_DIR = "./files"
@app.post("/download")
async def post_download(filename: str = Form(...)):
# 拼接文件路径,注意实际开发中需要做路径安全校验,避免目录遍历攻击
file_path = os.path.join(FILE_DIR, filename)
# 检查文件是否存在
if not os.path.exists(file_path):
return {"error": "文件不存在"}
3. 返回文件下载响应
使用StreamingResponse返回文件内容,同时设置Content-Disposition响应头指定下载的文件名:
from fastapi import FastAPI, Form
from fastapi.responses import StreamingResponse
import os
app = FastAPI()
FILE_DIR = "./files"
# 定义文件读取生成器,用于流式传输大文件
def file_iterator(file_path, chunk_size=1024*1024):
with open(file_path, "rb") as f:
while chunk := f.read(chunk_size):
yield chunk
@app.post("/download")
async def post_download(filename: str = Form(...)):
file_path = os.path.join(FILE_DIR, filename)
if not os.path.exists(file_path):
return {"error": "文件不存在"}
# 获取文件大小
file_size = os.path.getsize(file_path)
# 设置响应头
headers = {
"Content-Disposition": f"attachment; filename={filename}",
"Content-Length": str(file_size)
}
return StreamingResponse(
file_iterator(file_path),
media_type="application/octet-stream",
headers=headers
)
动态生成文件后下载
很多时候我们需要根据POST请求的参数动态生成文件再返回,比如根据用户输入的内容生成文本文件:
from fastapi import FastAPI, Form
from fastapi.responses import StreamingResponse
from io import BytesIO
app = FastAPI()
@app.post("/generate-download")
async def generate_file(content: str = Form(...), filename: str = Form(...)):
# 将内容写入内存中的字节流
file_obj = BytesIO()
file_obj.write(content.encode("utf-8"))
# 将指针移到开头
file_obj.seek(0)
headers = {
"Content-Disposition": f"attachment; filename={filename}"
}
return StreamingResponse(
file_obj,
media_type="text/plain",
headers=headers
)
常见问题与注意事项
- 路径安全:拼接文件路径时一定要做校验,避免用户传入
../等路径实现目录遍历,读取到非预期的文件。 - 大文件处理:对于大文件不要一次性读取到内存,使用生成器配合
StreamingResponse流式传输,避免占用过多内存。 - 响应头设置:必须正确设置
Content-Disposition头,否则浏览器可能会直接打开文件而不是触发下载。 - 文件类型:根据文件类型设置正确的
media_type,比如PDF文件可以设置为application/pdf,如果不明确类型可以使用通用的application/octet-stream。
测试验证
启动服务后,可以使用curl命令测试POST请求下载功能:
curl -X POST "http://127.0.0.1:8000/download" -F "filename=test.txt" -o test.txt
如果本地files目录下存在test.txt文件,执行上述命令后就会将文件下载到当前目录的test.txt中。
FastAPIPOST请求文件下载StreamingResponsePython修改时间:2026-07-14 00:45:31