[英]Content-Disposition:attachment not triggering download dialog
I've encountered some unexpected behavior when trying to create a file download functionality on my NodeJS server.尝试在我的 NodeJS 服务器上创建文件下载功能时,我遇到了一些意外行为。 I have a REST (express) API that calls for some export data function, which creates a CSV file on the server and uses res.download('path/to/file')
to trigger the download.我有一个 REST (express) API 需要一些导出数据 function,它在服务器上创建一个 CSV 文件并使用res.download('path/to/file')
触发下载。 Response headers include响应标头包括
Content-Disposition:attachment; filename="indicators.csv"
Content-Length:30125
Content-Type:text/csv; charset=UTF-8
so everything seems to be in order.所以一切似乎都井井有条。
The thing is, I get the response from the server as plain text.问题是,我以纯文本形式从服务器获得响应。 The response has all the data the CSV file contains, but does not trigger the browser's file download dialog like I intended.响应包含 CSV 文件包含的所有数据,但不会像我预期的那样触发浏览器的文件下载对话框。 I tried both on Chrome and FF.我在 Chrome 和 FF 上都试过了。 The problem persists in both.问题仍然存在。
Any ideas?有任何想法吗?
Update更新
I managed to make it work by creating a dummy form, and using its submit action to make my AJAX call.我设法通过创建一个虚拟表单并使用其提交操作来拨打我的 AJAX 电话来使其工作。 But it's an ugly hack, and I'm still looking for a more elegant solution.但这是一个丑陋的 hack,我仍在寻找更优雅的解决方案。
Headers are not the issue. 标题不是问题。 The issue is that you are querying the download url via an ajax
call, which will not invoke the browser download dialog. 问题是您通过ajax
调用查询下载URL,该调用不会调用浏览器下载对话框。 Your options boil down to the following: 您的选项可归结为以下内容:
Use a form that is submitted to your download url. 使用提交到您的下载URL的表单。 Instead of having a visible form a user has to interact with, create a form with JavaScript
and submit it programmatically by calling form.submit
- Handle file download from ajax post 用户不必使用可见的表单进行交互,而是使用JavaScript
创建表单并通过调用form.submit
编程方式提交form.submit
- 从ajax post form.submit
下载文件
Point window.location
to the download url. 将window.location
指向下载网址。 You can do this in the current window - download file using an ajax request , or in a new one - res.download() not working in my case 你可以在当前窗口中执行此操作 - 使用ajax请求下载文件 ,或者使用新的请求 - res.download()在我的情况下不起作用
You can try to use a different content-type, so that won't be open as a text file on the browser: 您可以尝试使用不同的内容类型,以便不会在浏览器上作为文本文件打开:
Content-Type:application/ms-excel; charset=UTF-8
Another alternative could be to use application/octet-stream as mime-type to define it as a downloadable file without a better description. 另一种替代方法可以是将application / octet-stream用作mime-type,将其定义为可下载文件而无需更好的描述。
Content-Type:application/octet-stream; charset=UTF-8
The question looks similar to this one 问题看起来与此类似
Show 'Save as' dialog box while downloading file from an Iframe through PHP 通过PHP从Iframe下载文件时显示“另存为”对话框
The basic idea is the second option that Roman described above, but this one's using an iframe to achieve it. 基本思想是Roman描述的第二个选项,但是这个选项使用iframe来实现它。
Inspired by Roman Pletnev, I recommend to wrap up the API response into a made up new document as follows (Vue/csv response):受 Roman Pletnev 的启发,我建议将 API 响应打包成一个新文档,如下所示(Vue/csv 响应):
API.get(apiName, path, myInit)
.then((response) => {
// console.log(response)
// Wrap this response into a temporary page that will trigger the download
const blob = new Blob([response.data], { type: 'text/csv' })
const blobURL = window.URL.createObjectURL(blob)
const tempLink = document.createElement('a')
tempLink.style.display = 'none'
tempLink.href = blobURL
tempLink.download = 'filename.csv'
tempLink.setAttribute('target', '_blank')
document.body.appendChild(tempLink)
tempLink.click()
document.body.removeChild(tempLink)
window.URL.revokeObjectURL(blobURL)
})
.catch((error) => {
console.log(error)
console.log(error.response);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.