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代码即可解决:
- 将
response.text()替换为response.blob()——因为Word文档是二进制文件,必须用Blob对象处理 - 创建临时的
<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
相关产品推荐
相关产品推荐

