Django后端返回xlsx文件响应为乱码符号无法下载如何解决
Django xlsx下载接口返回乱码问题修复
问题场景
开发Django后端文件下载接口时,xlsx格式响应异常,接口未触发文件下载行为,直接在响应体中输出乱码符号,无法正常下发Daily_Report.xlsx文件。
原有实现代码:
def daily_report_summery(request): body = request.body data = json.loads(body) date = data['date'] generate_summary_report_xl(date) with open('./Daily_Report.xlsx', "rb") as file: response = HttpResponse(file.read(),content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') response['Content-Disposition'] = 'attachment; filename=Daily_Report.xlsx' return response
异常响应效果:
核心需求:后端正确返回Daily_Report.xlsx文件供用户下载。
故障原因
- 直接使用
HttpResponse手动读取全量文件内容返回,大文件场景下容易出现内存占用过高、流传输异常问题,且未对响应头做兼容处理 - 若使用ajax/axios/fetch类异步请求调用接口,浏览器默认不会触发原生文件下载逻辑,会将二进制流直接当文本解析,直接展示乱码
- 前后端分离跨域场景下,未将
Content-Disposition加入CORS暴露头列表,前端无法识别下载相关配置 - 使用相对路径读取文件,服务部署后工作目录变化容易出现文件读取异常
修复方案
- 后端替换响应类为Django内置的
FileResponse,自动处理二进制流分块传输,同时将文件路径改为基于项目根目录的绝对路径,避免路径适配问题 - 非前后端分离场景直接用a标签、原生表单提交接口,不要用异步请求调用下载接口;若必须用异步请求,前端需要指定响应类型为二进制Blob,手动构造临时链接触发下载
- 跨域场景在CORS配置中暴露
Content-Disposition响应头,保证前端可正常读取下载配置
修复后后端代码
import os from django.http import FileResponse from django.conf import settings def daily_report_summery(request): data = json.loads(request.body) date = data['date'] generate_summary_report_xl(date) # 拼接绝对路径,适配所有部署环境 file_abs_path = os.path.join(settings.BASE_DIR, 'Daily_Report.xlsx') response = FileResponse( open(file_abs_path, 'rb'), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) # filename加双引号兼容特殊字符场景 response['Content-Disposition'] = 'attachment; filename="Daily_Report.xlsx"' return response
异步请求场景前端兼容代码(axios示例)
axios.post('/daily/report/summery', { date: '目标日期' }, { responseType: 'blob' // 必须指定响应类型为二进制blob }).then(res => { const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) const tempUrl = window.URL.createObjectURL(blob) const link = document.createElement('a') link.href = tempUrl link.download = 'Daily_Report.xlsx' document.body.appendChild(link) link.click() document.body.removeChild(link) window.URL.revokeObjectURL(tempUrl) })
跨域配置补充(使用django-cors-headers时)
在项目settings.py中添加如下配置:
CORS_EXPOSE_HEADERS = ['Content-Disposition']
内容的提问来源于stack exchange,提问作者Anirudh Sharma
相关产品推荐
相关产品推荐

