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

Flask实现无服务器存储Word文档并触发前端下载问题求助

问题

尝试用Flask实现点击按钮时,直接将服务器生成的Word文档发送给用户(文档不存储在服务器上)。目前通过JavaScript监听表单按钮点击事件,使用fetch向服务器发送请求,服务器能正常生成文档,但无法触发浏览器的文件下载。

相关代码如下:

Flask后端代码

document = Document()
document.add_heading("Some head-title")
document.add_paragraph('Some text')
f = BytesIO()
document.save(f)
f.seek(0)
return send_file(f, as_attachment=True, download_name='some.docx')

前端JS请求代码

fetch('/getData', {
    method : 'POST',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        someData: someData,
    })
})
.then(response => 
    response.text()
)
.then(response =>{
    console.log(response);
});

前端HTML代码

<form action="" name="getData" method="post" enctype="multipart/form-data">
<button type = "submit" name = "Download">Download</button>
</form>
解决方案

核心问题是:浏览器不会自动处理fetch请求返回的二进制文件流,需要手动创建下载链接触发下载。修改前端JavaScript代码即可解决:

  1. 将response.text()替换为response.blob()——因为Word文档是二进制文件,必须用Blob对象处理
  2. 创建临时的<a>标签,设置下载属性并模拟点击,触发浏览器下载行为

修改后的完整JS代码:

fetch('/getData', {
    method : 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        someData: someData,
    })
})
.then(response => response.blob())
.then(blob => {
    // 为Blob创建临时URL
    const fileUrl = window.URL.createObjectURL(blob);
    // 创建临时a标签
    const downloadLink = document.createElement('a');
    downloadLink.href = fileUrl;
    // 设置下载文件名(可与后端返回的文件名保持一致)
    downloadLink.download = 'some.docx';
    // 将a标签加入DOM
    document.body.appendChild(downloadLink);
    // 模拟点击触发下载
    downloadLink.click();
    // 清理临时资源
    document.body.removeChild(downloadLink);
    window.URL.revokeObjectURL(fileUrl);
});

额外注意事项:

  • 后端的send_file配置已经正确(as_attachment=True),无需修改
  • 前端请求中的Accept: application/json可以移除,因为我们接收的是二进制文件而非JSON
  • 如果希望从后端响应头自动获取文件名,可以解析Content-Disposition头:
    // 在获取response后添加
    const contentDisposition = response.headers.get('Content-Disposition');
    const filename = contentDisposition?.match(/filename="?([^"]+)"?/)?.[1] || 'some.docx';
    downloadLink.download = filename;
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:22:07