通过ajax下载文件

时间:2016-03-21 14:42:59

标签: javascript java jquery ajax spring

我需要通过ajax从服务器下载文件。问题是该文件未存储在服务器上。我的基于java的后端自动从请求参数生成文件,并在响应正文中返回:

  @RequestMapping(value = "/download", method = RequestMethod.GET)
  public void download(@RequestParam String description, @RequestParam Long logId, HttpServletResponse response) {
    try {
      InputStream fileContent = // getting file as byte stream
      response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
      response.setHeader("Content-Disposition", "attachment; filename=file.zip");
      ServletOutputStream responseOutputStream = response.getOutputStream();
      org.apache.commons.io.IOUtils.copy(fileContent, responseOutputStream);
      response.flushBuffer();
    } catch (IOException e) {
      logger.error("Attempt to download file failed", e);
    }
  }

所以我需要处理它并允许用户下载文件。 我的客户端包含这个:

$.ajax({
  type: "GET",
  url: "/download",
  data: {
    description: "test",
    logId: 123
  },
  success: function(data) {
    var blob = new Blob([data]);
    var link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = "file.zip";
    link.click();
  }
})

Controller返回文件,但没有任何反应。我究竟做错了什么?

2 个答案:

答案 0 :(得分:7)

不要进行AJAX调用,而是将窗口的href设置为指向用于下载文件的URL。然后将回复的内容类型更改为application/x-download,并将回复标题设置为Content-disposition

response.setContentType("application/x-download");
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
response.flushBuffer();

function download(fileName) {
    window.location.href = "/download?description=test&logId=123";
}

另外,请查看this SO post,它解决了与您拥有的问题类似的问题。

答案 1 :(得分:0)

对于那些寻求更现代方法的人,可以使用fetch API。以下示例显示如何下载PDF文件。使用以下代码即可轻松完成。

fetch(url, {
    body: JSON.stringify(data),
    method: 'POST',
    headers: {
        'Content-Type': 'application/json; charset=utf-8'
    },
})
.then(response => response.blob())
.then(response => {
    const blob = new Blob([response], {type: 'application/pdf'});
    const downloadUrl = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = downloadUrl;
    a.download = "file.pdf";
    document.body.appendChild(a);
    a.click();
})

我认为,这种方法比其他XMLHttpRequest解决方案更容易理解。而且,它的语法与jQuery方法类似,而无需添加任何其他库。

当然,我建议您检查一下要开发的浏览器,因为这种新方法不适用于IE。您可以在以下[link] [1]中找到完整的浏览器兼容性列表。

重要:在此示例中,我正在向侦听给定url的服务器发送JSON请求。必须设置此url,在我的示例中,我假设您知道这一部分。另外,请考虑您的请求正常工作所需的标头。由于我正在发送JSON,因此必须添加Content-Type标头并将其设置为application/json; charset=utf-8,以使服务器知道它将接收的请求的类型。

重要:使用fetch API向“ GET”请求发送参数将需要使用URLSearchParams界面。