小编典典

通过 jQuery.Ajax 下载文件

all

我在服务器端有一个用于文件下载的 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 中,我看到使用二进制流 检索数据。我想知道如何打开用户可以在本地保存文件的 文件下载窗口?


阅读 216

收藏
2022-03-14

共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 的方法

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

我创建了jQuery File Download,它允许通过 OnSuccess 和
OnFailure 回调完成文件下载的“类似
Ajax”体验,以提供更好的用户体验。看看我关于插件解决的常见问题和使用它的一些方法的博客文章,以及jQuery File
Download in action
的演示
。这里是

这是一个使用带有 Promise
的插件源
的简单用例演示。演示页面还包括许多其他“更好的
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 方法更明确的控制。

2022-03-14