我需要通过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返回文件,但没有任何反应。我究竟做错了什么?
答案 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
界面。