如何用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
相关产品推荐
相关产品推荐

