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

如何用Django+React(Axios)正确下载docx文件?文件大小内容异常

Axios下载DOCX文件出现大小异常、内容损坏的问题解决

我在使用Axios下载DOCX文件时遇到异常:源文件大小14KB,下载后变成22KB且内容损坏(源文件包含表格),但PDF和TXT文件下载正常。改用Fetch实现则能正常下载,Django后端代码无问题,需要Axios的解决方案并明确问题根源。

后端Django代码(view.py)

@method_decorator(csrf_exempt, name="dispatch")
class TestDownloadView(View):

    def post(self, request):
        filename = "./test.docx"
        with open(filename, "rb") as blank:
            content = blank.read()
            response = HttpResponse(
                content,
                content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
            )
            response["Content-Length"] = len(content)
            response["Content-Disposition"] = "attachment; filename=test.docx"
            return response

原Axios前端代码(App.tsx)

function App() {

        const dload = () => {
                axios.post('http://127.0.0.1:8000')
                        .then(response => {
                                const type = response.headers['content-type']
                                const href = URL.createObjectURL(new Blob([response.data], { type: type }));
                                const link = document.createElement('a');
                                link.href = href;
                                link.setAttribute('download', 'file.docx');
                                document.body.appendChild(link);
                                link.click();
                                document.body.removeChild(link);
                                URL.revokeObjectURL(href);
                        })
        }
        return (
                <>
                        <button onClick={dload}> Click </button>
                </>
        )
}

可正常工作的Fetch代码

fetch('http://127.0.0.1:8000', { method: "POST" })
        .then(response => response.blob())
        .then(blob => {
                const href = URL.createObjectURL(blob);
                const link = document.createElement('a');
                link.href = href;
                link.setAttribute('download', 'file.docx');
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                URL.revokeObjectURL(href);
        })

问题根源

问题出在Axios的默认响应处理逻辑:

  • Axios默认将响应数据解析为字符串(默认responseType为json,解析失败会 fallback 到text),而DOCX是二进制文件,转成字符串再转回Blob时,编码转换会导致字节丢失或篡改,最终文件变大且损坏。
  • Fetch的response.blob()直接保留原始二进制数据,因此能正常下载。

Axios解决方案

给Axios请求设置responseType: 'blob',让Axios直接以Blob格式接收二进制数据,避免编码转换:

修改后的Axios代码:

function App() {

        const dload = () => {
                axios.post('http://127.0.0.1:8000', {}, {
                        responseType: 'blob' // 关键配置
                })
                        .then(response => {
                                const type = response.headers['content-type']
                                const href = URL.createObjectURL(response.data); // 直接使用已为Blob格式的response.data
                                const link = document.createElement('a');
                                link.href = href;
                                link.setAttribute('download', 'file.docx');
                                document.body.appendChild(link);
                                link.click();
                                document.body.removeChild(link);
                                URL.revokeObjectURL(href);
                        })
        }
        return (
                <>
                        <button onClick={dload}> Click </button>
                </>
        )
}

补充说明:

  • 如果POST请求需要发送数据,将数据放在第二个参数位置,第三个参数为配置项(包含responseType)。
  • 对于Excel、压缩包等其他二进制文件,同样需要设置responseType: 'blob'避免类似问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 02:59:58