我有一个javascript应用程序,发送ajax POST请求到某个URL。Response可以是JSON字符串,也可以是文件(作为附件)。我可以很容易地在ajax调用中检测到Content-Type和Content-Disposition,但是一旦我检测到响应包含一个文件,我如何让客户端下载它呢?我在这里读过一些类似的帖子,但没有一个能提供我想要的答案。

请,请,请不要发布建议我不应该使用ajax或我应该重定向浏览器的答案,因为这些都不是一个选项。使用普通的HTML表单也是不可行的。我所需要的是向客户端显示一个下载对话框。这能做到吗?如何做到?


当前回答

对于那些从Angular角度寻找解决方案的人来说,这对我来说很管用:

$http.post(
  'url',
  {},
  {responseType: 'arraybuffer'}
).then(function (response) {
  var headers = response.headers();
  var blob = new Blob([response.data],{type:headers['content-type']});
  var link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = "Filename";
  link.click();
});

其他回答

对于那些寻找更现代的方法的人,您可以使用fetch API。下面的代码展示了如何下载电子表格文件。

fetch(url, {
    body: JSON.stringify(data),
    method: 'POST',
    headers: {
        'Content-Type': 'application/json; charset=utf-8'
    },
})
.then(response => response.blob())
.then(response => {
    const blob = new Blob([response], {type: 'application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
    const downloadUrl = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = downloadUrl;
    a.download = "file.xlsx";
    document.body.appendChild(a);
    a.click();
})

我相信这种方法比其他XMLHttpRequest解决方案更容易理解。此外,它具有与jQuery方法相似的语法,不需要添加任何额外的库。

当然,我建议检查一下你正在开发的浏览器,因为这种新方法在IE上行不通。您可以在以下[链接][1]上找到完整的浏览器兼容性列表。

重要提示:在本例中,我将发送一个JSON请求到侦听给定url的服务器。这个url必须设置,在我的例子中,我假设你知道这一部分。另外,考虑请求工作所需的头文件。因为我发送一个JSON,我必须添加内容类型头,并将其设置为application/ JSON;Charset =utf-8,以便让服务器知道它将接收的请求类型。

这是一个3年前的问题,但我今天遇到了同样的问题。我看了你编辑的解决方案,但我认为它可以牺牲性能,因为它必须做出双重请求。因此,如果有人需要另一个解决方案,不暗示调用服务两次,那么这是我做的方式:

<form id="export-csv-form" method="POST" action="/the/path/to/file">
    <input type="hidden" name="anyValueToPassTheServer" value="">
</form>

此表单仅用于调用服务,避免使用window.location()。在此之后,您只需简单地使用jquery提交一个表单,以便调用服务并获取文件。这很简单,但是通过这种方式你可以使用POST进行下载。我现在知道,如果您调用的服务是GET,这可能会更容易,但我的情况不是这样。

正如其他人所述,您可以通过POST请求创建并提交表单来下载。但是,您不必手动执行此操作。

有一个非常简单的库可以做到这一点,那就是jquery.redirect。它提供了一个类似于标准jQuery的API。post方法:

$.redirect(url, [values, [method, [target]]])

参见:http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/ 它将返回一个blob作为响应,然后可以将其放入文件保存器

创建一个表单,使用POST方法,提交表单-不需要iframe。当服务器页面响应请求时,为文件的mime类型写一个响应头,它将呈现一个下载对话框——我已经做过很多次了。

你想要内容类型的应用程序/下载-只要搜索如何为你使用的任何语言提供下载。