【问题标题】:How to download file from server using jQuery AJAX and Spring MVC 3如何使用 jQuery AJAX 和 Spring MVC 3 从服务器下载文件
【发布时间】:2011-10-07 01:17:39
【问题描述】:

我想实现从服务器下载(使用 AJAX)上传的文件。在服务器端我写了代码

@RequestMapping(value = "/getInvoice/approvalId/{approvalId}", method = RequestMethod.GET)
public
@ResponseBody
byte[] getInvoice(@PathVariable("approvalId") Integer approvalId, HttpServletResponse response) throws IOException {
    String fileName = this.approvalService.getFullInvoicePath(approvalId);
    File file = new File(fileName);

    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
    response.setHeader("Pragma", "no-cache");
    response.setHeader("Cache-Control", "no-cache");
    response.setContentLength((int) file.length());
    return FileUtils.readFileToByteArray(file);
}

Fiddler2 显示响应:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Disposition: attachment; filename="invoice.pdf"
Pragma: no-cache
Cache-Control: no-cache
Content-Type: application/octet-stream;charset=UTF-8
Content-Length: 1028351
Date: Sun, 17 Jul 2011 08:16:41 GMT

%PDF-1.4
%����
6 0 obj <</Linearized 1/L 1028351/O 8/E 1024254/N 1/T 1028185/H [ 5056 544]>>
endobj

xref
6 238 
*** FIDDLER: RawDisplay truncated at 128 characters. Right-click to disable truncation. ***

如何处理和强制浏览器使用jQuery下载文件?

【问题讨论】:

标签: jquery spring-mvc download


【解决方案1】:

通常使用两个选项,但都不涉及 AJAX。并且 jQuery 也不会有很大的帮助。

选项 1:IFrame

在您的页面中放置一个不可见 IFrame:

<iframe id="downloadFrame" style="display:none"></iframe>

当下载应该开始时(你没有提到它是如何触发的),使用 Javascript(可能还有 jQuery)来设置 IFrame 的 URL,在你的情况下类似于 /getInvoice/approvalId/123

var iframe = document.getElementById("downloadFrame");
iframe .src = "/getInvoice/approvalId/123";

设置 IFrame URL 应该会触发浏览器显示下载对话框。

选项 2:导航到下载 URL

第二个选项更简单。只需导航到下载 URL。一旦浏览器发现它是一个无法显示的 MIME 类型,它就会显示一个下载对话框。

所以当触发下载时,执行以下 JavaScript 代码:

window.location.href = "/getInvoice/approvalId/123";

注意

我不确定是否所有浏览器都能可靠地显示包含 PDF 文件的下载对话框。某些浏览器可能会尝试在浏览器本身中显示它。 Content-Disposition HTTP 标头很有帮助,但不能保证。

【讨论】:

  • 我决定不使用@ResponseBody 返回字节[]。现在我设置响应头
     private void setPdfHeaders(HttpServletResponse response, String shortFileName, File file) { response.setContentType("application/pdf"); response.setHeader("内容配置", "附件; filename=" + shortFileName); response.setHeader("内容长度", String.valueOf(file.length())); }
    然后将流写入响应 OutputStream 和您推荐的用户选项 2。
  • 我喜欢 iframe 选项,但想添加注释。从服务器提供文档时,您需要适当地设置 mime-type,否则您将无法获得正确的浏览器对话框交互。例如,我的后端正在为 .xlsx 文档设置“text/plain”,但没有任何乐趣。
【解决方案2】:

Codo 的 jQuery 化答案:

$('#downloadFrame').remove(); // 如果框架不存在,这不应该失败 $('body').append(''); $('#downloadFrame').attr('src','/downloadUrlGoesHere');

【讨论】:

    【解决方案3】:

    【讨论】:

    • 很遗憾,出于明显的安全原因,您无法以编程方式单击链接。
    猜你喜欢
    • 2018-02-21
    • 2014-12-30
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    相关资源
    最近更新 更多