首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >通过jQuery.Ajax下载文件

通过jQuery.Ajax下载文件
EN

Stack Overflow用户
提问于 2010-12-28 18:21:29
回答 24查看 890.6K关注 0票数 463

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

代码语言:javascript
复制
<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调用操作时:

代码语言:javascript
复制
$.post(
  "/download.action",{
    para1:value1,
    para2:value2
    ....
  },function(data){
      console.info(data);
   }
);

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

EN

回答 24

Stack Overflow用户

回答已采纳

发布于 2012-04-02 11:48:04

2019现代浏览器更新

这是我现在推荐的方法,但有几个警告:

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

代码语言:javascript
复制
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,它通过OnSuccess和OnFailure回调来提供更好的用户体验,从而提供类似Ajax的文件下载体验。看看我关于插件解决的常见问题的blog post,以及一些使用它的方法,还有一个demo of jQuery File Download in action。这是source

这是一个简单的用例演示,使用带有promises的插件sourcedemo page还包括许多其他的“更好的用户体验”的例子。

代码语言:javascript
复制
$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

根据您需要支持的浏览器,您可以使用https://github.com/eligrey/FileSaver.js/,它允许比jQuery文件下载使用的IFRAME方法更显式的控制。

票数 737
EN

Stack Overflow用户

发布于 2011-10-05 19:50:29

没有人发布了这条...所以我会把它贴出来。它可以帮助某些人。

您不需要通过Ajax来完成此操作。只需使用

代码语言:javascript
复制
window.location="download.action?para1=value1...."
票数 242
EN

Stack Overflow用户

发布于 2015-04-29 17:03:45

使用HTML5,您可以使用

注意:返回的文件数据必须是base64编码的,因为您不能对二进制数据进行JSON编码

在我的AJAX响应中,我有一个如下所示的数据结构:

代码语言:javascript
复制
{
    result: 'OK',
    download: {
        mimetype: string(mimetype in the form 'major/minor'),
        filename: string(the name of the file to download),
        data: base64(the binary data as base64 to download)
    }
}

这意味着我可以通过AJAX执行以下操作来保存文件

代码语言:javascript
复制
var a = document.createElement('a');
if (window.URL && window.Blob && ('download' in a) && window.atob) {
    // Do it the HTML5 compliant way
    var blob = base64ToBlob(result.download.data, result.download.mimetype);
    var url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = result.download.filename;
    a.click();
    window.URL.revokeObjectURL(url);
}

函数base64ToBlob取自here,必须符合此函数的要求使用

代码语言:javascript
复制
function base64ToBlob(base64, mimetype, slicesize) {
    if (!window.atob || !window.Uint8Array) {
        // The current browser doesn't have the atob function. Cannot continue
        return null;
    }
    mimetype = mimetype || '';
    slicesize = slicesize || 512;
    var bytechars = atob(base64);
    var bytearrays = [];
    for (var offset = 0; offset < bytechars.length; offset += slicesize) {
        var slice = bytechars.slice(offset, offset + slicesize);
        var bytenums = new Array(slice.length);
        for (var i = 0; i < slice.length; i++) {
            bytenums[i] = slice.charCodeAt(i);
        }
        var bytearray = new Uint8Array(bytenums);
        bytearrays[bytearrays.length] = bytearray;
    }
    return new Blob(bytearrays, {type: mimetype});
};

如果您的服务器正在转储要保存的文件数据,这是很好的。但是,我还没有完全弄清楚如何实现HTML4回退

票数 44
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4545311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档