You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过FastAPI下载大文件?解决UnicodeDecodeError编码错误

FastAPI返回大.tar.gz文件时UnicodeDecodeError问题解决

问题背景

需要从FastAPI后端下载大.tar.gz文件,服务端验证文件路径后使用Starlette的FileResponse返回文件,代码如下:

return FileResponse(path=file_name, media_type='application/octet-stream', filename=file_name)

触发的错误

执行时抛出UnicodeDecodeError,错误栈信息:

File "/usr/local/lib/python3.10/dist-packages/fastapi/routing.py", line 149, in serialize_response
    return jsonable_encoder(response_content)
File "/usr/local/lib/python3.10/dist-packages/fastapi/encoders.py", line 130, in jsonable_encoder
    return ENCODERS_BY_TYPE[type(obj)](obj)
File "pydantic/json.py", line 52, in pydantic.json.lambda
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

尝试改用StreamingResponse

切换为StreamingResponse实现流式返回,代码如下,但仍触发相同错误:

@x.post("/download")
async def download(file_name=Body(), token: str | None = Header(default=None)):
    file_name = file_name["file_name"]
    # 文件格式类似xx.tar
    def iterfile():
        with open(file_name,"rb") as f:
            yield from f
    return StreamingResponse(iterfile(),media_type='application/octet-stream')

根因定位

经排查,错误并非出自下载API,而是转发该请求的API。转发代码如下:

@("/")
def f():
    req = requests.post(url ="/download")
    return req.content

直接返回req.content(二进制字节流)时,FastAPI会默认调用jsonable_encoder尝试将其序列化为JSON,而二进制压缩文件的字节无法被UTF-8解码,因此触发编码错误。

解决办法

在转发请求的API中,返回时显式指定media_type为application/octet-stream,确保FastAPI将响应识别为二进制流而非JSON。修改后的转发代码示例:

from fastapi import Response

@("/")
def f():
    req = requests.post(url ="/download")
    return Response(content=req.content, media_type='application/octet-stream')

通过指定正确的媒体类型,FastAPI会直接返回二进制内容,不再尝试JSON序列化,编码错误问题得以解决。

内容的提问来源于stack exchange,提问作者Yuqi Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:03:27