FastAPI 文件上传/下载的三个坑,你踩过几个?
你以为 FastAPI 封装得够好了,随便写两句就能跑?天真
做后端开发,文件上传和下载是绕不过去的坎。FastAPI 的封装确实优雅,但如果你以为随便写两句就能高枕无忧,那可就太天真了。今天,我们就来盘点三个在实际项目中高频踩坑的场景,看看你中招了几条。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

坑一:大文件上传,内存原地爆炸
很多新手第一次写文件上传接口,大概率会这么写:
from fastapi import FastAPI, UploadFile
import shutil
app = FastAPI()
@app.post("/upload")
async def upload_file(file: UploadFile):
contents = await file.read()
with open(f"./uploads/{file.filename}", "wb") as f:
f.write(contents)
return {"filename": file.filename}
乍一看没毛病,用 Postman 一测,小文件秒传,信心瞬间爆棚。然而,当产品经理扔过来一个 500MB 的视频文件时,接口直接 OOM(内存溢出),进程当场挂掉。
问题出在哪里?关键就在 await file.read() 这一行。它一次性把整个文件流都读进了内存,这谁顶得住?
正确的做法是采用流式写入,让内存压力降到最低:
@app.post("/upload")
async def upload_file(file: UploadFile):
sa ve_path = f"./uploads/{file.filename}"
with open(sa ve_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {"filename": file.filename}
shutil.copyfileobj 会自己管理缓冲区,将文件数据一块一块地写入磁盘,内存占用可以稳定控制在几 MB 以内。说到底,这个坑的教训就是:别贪图方便,试图一口吞下整个文件流。
坑二:文件下载,中文文件名 URL 乱码
后端接口写得漂漂亮亮,前端调用也一切顺利,结果用户下载下来的文件名变成了一串 %E4%B8%AD%E6%96%87 这样的“天书”,用户体验直接归零。
这其实不算是你的 Bug,而是 HTTP 协议中 URL 编码规则导致的。根据 RFC 5987 标准,如果文件名包含非 ASCII 字符(比如中文),就必须使用 encodeURIComponent 或者 RFC 5987 规定的 filename* 语法来处理。
最稳妥的做法,是在响应头里同时提供两个选项:
from fastapi import Response
import os
from urllib.parse import quote
@app.get("/download/{filename}")
async def download_file(filename: str, response: Response):
file_path = f"./uploads/{filename}"
if not os.path.exists(file_path):
return {"error": "文件不存在"}
# 兼容中文文件名
safe_name = os.path.basename(filename)
response.headers["Content-Disposition"] = (
f"attachment; filename={safe_name}; "
f"filename*=UTF-8''{quote(safe_name)}"
)
return Response(
open(file_path, "rb").read(),
media_type="application/octet-stream",
headers=response.headers
)
简单解释一下:filename 供现代浏览器使用,而 filename*=UTF-8'' 则为老式浏览器提供兜底方案。两者并存时,浏览器会自动选择它能理解的那个。另外,别忘了导入 from urllib.parse import quote。
坑三:文件类型不校验,后端成了木马上传入口
很多教程讲到文件上传就戛然而止,对文件类型校验只字不提。这在内部系统中或许还能接受,但对于任何有基本安全要求的系统,这无疑是一个高危漏洞。
想象一下,如果你的接口允许上传 .py 文件,攻击者完全可以上传一个能执行系统命令的脚本,然后直接访问它——这跟 SSRF(服务器端请求伪造)漏洞的危害不相上下。
最基础的防护手段,是同时校验文件扩展名和 MIME 类型:
ALLOWED_EXTENSIONS = {"jpg", "jpeg", "png", "pdf", "docx"}
ALLOWED_MIME_TYPES = {"image/jpeg", "image/png", "application/pdf", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}
@app.post("/upload")
async def upload_file(file: UploadFile):
ext = file.filename.rsplit(".", 1)[-1].lower() if "." in file.filename else ""
if ext not in ALLOWED_EXTENSIONS:
return {"error": f"不支持的文件类型: .{ext}"}
if file.content_type not in ALLOWED_MIME_TYPES:
return {"error": f"不支持的MIME类型: {file.content_type}"}
sa ve_path = f"./uploads/{file.filename}"
with open(sa ve_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {"filename": file.filename}
当然,如果对安全性有更高要求,更佳实践是将文件直接存储到对象存储(如 OSS / S3)中,后端只返回一个具有时效性的临时访问链接,彻底杜绝用户直接访问服务器文件路径的可能性。这又是另一个话题了,有机会可以单独展开聊聊。
总结
三个高频坑点讲完了。回过头看,其实都是非常基础的问题:处理大文件要流式操作、中文文件名需规范编码、上传文件必须校验类型。说难吗?并不复杂。说简单吗?却总有人栽跟头。关键就在于,写代码时脑子里得时刻绷紧这根弦。把这些细节做到位,你的服务才能既稳健又安全。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
CP+ 2026 佳能研发团队专访 光学突破、概念探索与 PowerShot 三十载焕新
2026 年 CP+ 相机与影像博览会:佳能的坚守、洞察与未来探索 2026年的 CP+ 相机与影像博览会,对于佳能而言,更像是一场面向未来的深度对话。围绕 RF 镜头技术、全新模拟概念相机以及迎来而立之年的 PowerShot 系列,佳能的多位核心研发、企划与设计负责人悉数登场,详尽解读了品牌在光
2026 荣耀 MagicV6 值得买吗?折叠屏旗舰全面解析
随着折叠屏手机技术的不断成熟,越来越多消费者开始关注这一形态的旗舰机型。在 2026 年的高端手机市场中,荣耀 Magic V6 成为讨论度极高的一款产品。 因此,当你考虑入手一台折叠旗舰时,很可能绕不开那个经典提问:荣耀 Magic V6,究竟值不值得买?从产品定位和核心配置来看,答案其实已相当清
中国第一:阿里通义千问 3.5-Max-Preview 首发亮相 LM Arena 国际大模型竞技场
中国第一:阿里通义千问 3 5-Max-Preview 首发亮相 LM Arena 国际大模型竞技场 大模型赛道的竞争,从来都不缺乏看点。这不,阿里千问家族又添新丁了。3月20日,千问3 5系列的旗舰预览版——Qwen3 5-Max-Preview,正式在全球知名的LM Arena竞技场上线参战,并
2026 最强的折叠屏手机荣耀 Magic V6 重塑旗舰标杆
2026 最强的折叠屏手机荣耀 Magic V6 重塑旗舰标杆 折叠屏市场早已跨过了“尝鲜”阶段,如今用户要的,是真正无短板的顶级体验。在这条赛道上,荣耀一直是个不容忽视的引领者,每次出手,总能带来些新东西。时间来到2026年3月,荣耀Magic V6正式登场。这一次,它凭借全方位的技术突破和体验升
金蝶张志兵:让 AI 成为“数字员工”
数字化是基础,AI 是放大器,进化的关键在于“持续”。 在金蝶创见者城市峰会的“AI+ 制造”论坛上,金蝶中国 AIEBC 产品管理部总经理张志兵,围绕金蝶 AI 星空,系统阐述了其支撑制造企业智能化转型的核心能力框架。 下文内容源于其实时演讲的精要摘编。 核心主张:面向未来,持续进化 AI技术的迭
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

