通过 jQuery.Ajax 下载文件

2022-08-29 23:10:46

我在服务器端有一个Struts2操作用于文件下载。

<action name="download" class="com.xxx.DownAction">
    <result name="success" type="stream">
        <param name="contentType">text/plain</param>
        <param name="inputName">imageStream</param>
        <param name="contentDisposition">attachment;filename={fileName}</param>
        <param name="bufferSize">1024</param>
    </result>
</action>

但是,当我使用jQuery调用操作时:

$.post(
  "/download.action",{
    para1:value1,
    para2:value2
    ....
  },function(data){
      console.info(data);
   }
);

在Firebug中,我看到数据是用二进制流检索的。我想知道如何打开文件下载窗口,用户可以在其中将文件保存在本地?


答案 1

2019年现代浏览器更新

这是我现在推荐的方法,但需要注意一些:

  • 需要一个相对现代的浏览器
  • 如果预计文件非常大,则可能应执行与原始方法(iframe 和 cookie)类似的操作,因为以下某些操作可能消耗的系统内存至少与正在下载的文件一样大和/或其他有趣的 CPU 副作用。

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(resp => resp.blob())
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    // the filename you want
    a.download = 'todo-1.json';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    alert('your file has downloaded!'); // or you know, something with better UX...
  })
  .catch(() => alert('oh no!'));

2012 原创 jQuery/iframe/Cookie 基于方法

Bluish对此是完全正确的,你不能通过Ajax做到这一点,因为JavaScript不能将文件直接保存到用户的计算机(出于安全考虑)。不幸的是,将主窗口的URL指向文件下载意味着您几乎无法控制文件下载时的用户体验。

我创建了jQuery File Download,它允许“Ajax like”体验,文件下载配有OnSuccess和OnFailure回调,以提供更好的用户体验。看看我的博客文章,了解插件解决的常见问题以及使用它的一些方法,以及jQuery文件下载的实际演示。这是来源

这是一个简单的用例演示,使用带有承诺的插件演示页面还包括许多其他“更好的UX”示例。

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

根据您需要支持的浏览器,您可能能够使用 https://github.com/eligrey/FileSaver.js/ 这比jQuery File Download使用的IFRAME方法更明确地控制。


答案 2

没有人发布这个@Pekka的解决方案...所以我会发布它。它可以帮助某人。

您不需要通过Ajax执行此操作。只需使用

window.location="download.action?para1=value1...."