通过jQuery.Ajax下载文件

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


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

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

这是一个简单的用例演示,使用带有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方法更明确的控制。


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

你不能也不需要通过Ajax来做到这一点。 只需使用

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

1.框架不可知:Servlet下载文件作为附件

<!-- with JS -->
<a href="javascript:window.location='downloadServlet?param1=value1'">
    download
</a>

<!-- without JS -->
<a href="downloadServlet?param1=value1" >download</a>

2. Struts2框架:动作下载文件作为附件

<!-- with JS -->
<a href="javascript:window.location='downloadAction.action?param1=value1'">
    download
</a>

<!-- without JS -->
<a href="downloadAction.action?param1=value1" >download</a>

使用<s:a>标签指向OGNL指向使用<s:url>标签创建的URL会更好:

<!-- without JS, with Struts tags: THE RIGHT WAY -->    
<s:url action="downloadAction.action" var="url">
    <s:param name="param1">value1</s:param>
</s:ulr>
<s:a href="%{url}" >download</s:a>

在上述情况下,您需要将Content-Disposition标头写入响应,指定文件需要下载( attachment ),而不是由浏览器打开( inline )。 您还需要指定内容类型,并且您可能需要添加文件名称和长度(以帮助浏览器绘制逼真的进度条)。

例如,下载ZIP时:

response.setContentType("application/zip");
response.addHeader("Content-Disposition", 
                   "attachment; filename="name of my file.zip"");
response.setHeader("Content-Length", myFile.length()); // or myByte[].length...

使用Struts2(例如,除非您将Action作为Servlet使用,例如直接流式传输),则无需直接向响应写入任何内容; 只需使用Stream结果类型并在struts.xml中对其进行配置即可:示例

<result name="success" type="stream">
   <param name="contentType">application/zip</param>
   <param name="contentDisposition">attachment;filename="${fileName}"</param>
   <param name="contentLength">${fileLength}</param>
</result>

3.框架不可知(/ Struts2框架):Servlet(/ Action)在浏览器内部打开文件

如果您想要在浏览器内打开文件,而不是下载文件,Content-disposition必须设置为内联,但目标不能是当前的窗口位置; 您必须定位一个由javascript创建的新窗口,该页面中的<iframe>或者与“讨论过的”target =“_ blank”实时创建的新窗口:

<!-- From a parent page into an IFrame without javascript -->   
<a href="downloadServlet?param1=value1" target="iFrameName">
    download
</a>

<!-- In a new window without javascript --> 
<a href="downloadServlet?param1=value1" target="_blank">
    download
</a>

<!-- In a new window with javascript -->    
<a href="javascript:window.open('downloadServlet?param1=value1');" >
    download
</a>
链接地址: http://www.djcxy.com/p/51955.html

上一篇: Download a file by jQuery.Ajax

下一篇: Return link for another (same) XMLHttpRequest