VueJS下载Flask生成的docx文件时文件损坏问题求助
问题:Vue下载Flask生成的docx文件损坏
我尝试在VueJS中实现docx文件下载功能,前端生成文件时出现损坏,改用Flask后端生成docx(本地保存可正常打开),但传输到前端下载后文件仍损坏。相关代码如下:
Flask API 代码
def download_docx(): try: data = request.get_json() write_to_docx = data.get('docxData') document = Document() new_parser = HtmlToDocx() new_parser.add_html_to_document(write_to_docx, document) docx_file = BytesIO() file_name = "test.docx" document.save(docx_file) docx_file.seek(0) return send_file(docx_file, attachment_filename=file_name, as_attachment=True, mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document', cache_timeout=0) except Exception as e: print(traceback.print_exc()) return render_template('index.html')
VueJS 代码
请求函数
export function downloadDocx(token, data) { const headers = authHeader(token) return mainAxios.post(`${API_URL}/download/docx`, data, { headers }) }
下载方法
downloadDocx() { let data = { docxData: this.fullHtml } this.$store.dispatch('downloadDocx', data) .then(response => { if (response.data && response.status == 200) { const blob = new Blob([ response.data ], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }) const url = URL.createObjectURL(blob); var element = document.createElement('a'); element.setAttribute('href', url); element.setAttribute('download', 'test.docx'); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); } else { console.log("FAILED") } }) }
解决方案
问题核心是Axios默认将响应解析为JSON,导致二进制docx文件被错误编码,最终损坏。需要做以下修改:
1. 修改Axios请求配置,指定响应类型为blob
在Vue的请求函数中添加responseType: 'blob',确保Axios以二进制形式接收文件:
export function downloadDocx(token, data) { const headers = authHeader(token) return mainAxios.post(`${API_URL}/download/docx`, data, { headers, responseType: 'blob' // 关键配置 }) }
2. 优化前端Blob处理逻辑
由于已指定responseType: 'blob',response.data本身就是Blob对象,无需再次封装,同时添加URL对象释放逻辑避免内存泄漏:
downloadDocx() { let data = { docxData: this.fullHtml } this.$store.dispatch('downloadDocx', data) .then(response => { if (response.data && response.status == 200) { const url = URL.createObjectURL(response.data); const element = document.createElement('a'); element.href = url; element.download = 'test.docx'; element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); URL.revokeObjectURL(url); // 释放URL对象 } else { console.log("FAILED") } }) }
3. 可选:Flask端补充配置
Flask的send_file已配置正确mimetype,可额外添加conditional=False避免条件请求可能引发的缓存问题:
return send_file(docx_file, attachment_filename=file_name, as_attachment=True, mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document', cache_timeout=0, conditional=False)
内容的提问来源于stack exchange,提问作者asm
相关产品推荐
相关产品推荐

