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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:20:27