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

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


当前回答

我是这么做的 https://stackoverflow.com/a/27563953/2845977

. ajax({美元 url: ' < URL_TO_FILE >”, 成功:函数(数据){ var blob=new blob ([data]); var链接= document.createElement (' a '); link.href = window.URL.createObjectURL (blob); link.download = " < FILENAME_TO_SAVE_WITH_EXTENSION >”; link.click (); } });

使用download.js更新答案

. ajax({美元 url: ' < URL_TO_FILE >”, 成功:下载。绑定(true, "<FILENAME_TO_SAVE_WITH_EXTENSION>", "<FILE_MIME_TYPE>") });

其他回答

对于那些从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();
});

我使用这个FileSaver.js。在我的情况下,与csv文件,我这样做(在coffescript):

  $.ajax
    url: "url-to-server"
    data: "data-to-send"
    success: (csvData)->
      blob = new Blob([csvData], { type: 'text/csv' })
      saveAs(blob, "filename.csv")

我认为对于大多数复杂的情况,必须对数据进行正确的处理。在底层,filesver .js实现了与Jonathan Amend的答案相同的方法。

我也遇到过同样的问题,并成功地解决了它。我的用例是这样的。

“将JSON数据发送到服务器并接收一个excel文件。 该excel文件由服务器创建,并作为响应返回给客户机。在浏览器中下载具有自定义名称的响应文件”

$("#my-button").on("click", function(){

// Data to post
data = {
    ids: [1, 2, 3, 4, 5]
};

// Use XMLHttpRequest instead of Jquery $ajax
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    var a;
    if (xhttp.readyState === 4 && xhttp.status === 200) {
        // Trick for making downloadable link
        a = document.createElement('a');
        a.href = window.URL.createObjectURL(xhttp.response);
        // Give filename you wish to download
        a.download = "test-file.xls";
        a.style.display = 'none';
        document.body.appendChild(a);
        a.click();
    }
};
// Post data to URL which handles post request
xhttp.open("POST", excelDownloadUrl);
xhttp.setRequestHeader("Content-Type", "application/json");
// You should set responseType as blob for binary responses
xhttp.responseType = 'blob';
xhttp.send(JSON.stringify(data));
});

上面的代码片段只是执行以下操作

使用XMLHttpRequest将数组作为JSON发送到服务器。 在获取内容作为一个blob(二进制)后,我们正在创建一个可下载的URL,并将其附加到不可见的“a”链接,然后单击它。

这里我们需要小心地在服务器端设置一些东西。我在Python Django HttpResponse中设置了几个头。如果使用其他编程语言,则需要相应地设置它们。

# In python django code
response = HttpResponse(file_content, content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")

由于我在这里下载xls(excel),我将contentType调整为1以上。您需要根据您的文件类型设置它。您可以使用这种技术下载任何类型的文件。

我使用了Naren Yellavula的解决方案,并在使用jquery尝试其他几个解决方案后,对脚本进行了很少的更改。但是,jquery将不能正确下载zip文件。下载后我无法解压缩文件。 在我的用例中,我必须上传一个压缩文件,该文件在Servlet中解压缩,在压缩文件下载到客户端之前,文件被处理并再次压缩。这是你在客户端需要做的事情。

$('#fileUpBtn').click(function (e){ e.preventDefault(); var file = $('#fileUpload')[0].files[0]; var formdata = new FormData(); formdata.append('file', file); // Use XMLHttpRequest instead of Jquery $ajax to download zip files xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (xhttp.readyState === 4 && xhttp.status === 200) { var a = document.createElement('a'); a.href = window.URL.createObjectURL(xhttp.response); a.download = "modified_" + file.name; a.style.display = 'none'; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(a.href); } }; xhttp.open("POST", "<URL to Servlet>", true); xhttp.responseType = 'blob'; xhttp.send(formdata); }); <div class="form-group"> <label id="fileUpLabel" for="fileUpload"></label> <input type="file" class="form-control" id="fileUpload" name="file" accept="" required/> </div> <button class="btn" type="submit" id="fileUpBtn"></button>

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

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