FastAPI如何返回含Unicode/非ASCII字符的JSON/CSV响应?
FastAPI StreamingResponse 下载含特殊字符文件的编码问题解决
JSON 下载问题解决
你的JSON中é变为\u00e9,是因为json.dumps()默认开启ensure_ascii=True,会把所有非ASCII字符转义成Unicode转义序列。要保留原始字符,需关闭该参数,同时改用字节流传递内容,避免StreamingResponse处理文本时的编码偏差。
修改后的JSON端点代码:
@app.get("/download_json") async def download_json(): # 关闭ASCII转义,生成UTF-8格式的字符串 json_str = json.dumps(data, ensure_ascii=False) # 将字符串转为字节流,确保编码准确 buffer = io.BytesIO(json_str.encode("utf-8")) return StreamingResponse( buffer, media_type="application/json; charset=utf-8", headers={ "Content-Disposition": 'attachment; filename="data.json"' } )
CSV 下载问题解决
CSV中é变为Ãé是典型的UTF-8字符被误当作Latin-1解码的问题。根源是你用io.StringIO存储CSV文本,StreamingResponse处理文本流时会采用系统默认编码(如Latin-1)转成字节,导致编码错误。正确做法是直接生成UTF-8字节流,用io.BytesIO传递。
修改后的CSV端点代码:
@app.get("/download_csv") async def download_csv(): buffer = io.BytesIO() # 直接将CSV写入字节流,指定UTF-8编码 pd.DataFrame(data).to_csv(buffer, index=False, encoding="utf-8") # 重置流指针到起始位置 buffer.seek(0) return StreamingResponse( buffer, media_type="text/csv; charset=utf-8", headers={ "Content-Disposition": 'attachment; filename="data.csv"' } )
关键修改总结
- JSON:关闭
json.dumps的ensure_ascii参数,改用字节流传递内容 - CSV:直接生成UTF-8字节流,避免文本流的编码转换损耗
- 统一设置正确的
media_type和Content-Disposition(必须包含attachment触发浏览器下载,文件名用引号包裹可避免特殊字符解析问题)
内容的提问来源于stack exchange,提问作者KYPcode
相关产品推荐
相关产品推荐

