I need to download file from server via ajax. The problem is that the file is not stored on server. My java-based backend automatically generates file from request parameters and returns it in response body:
@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.apachemons.io.IOUtils.copy(fileContent, responseOutputStream);
response.flushBuffer();
} catch (IOException e) {
logger.error("Attempt to download file failed", e);
}
}
So i need to handle it and allow user to download file. My client side contains this:
$.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 returns file, but then nothing happens. What am i doing wrong?
I need to download file from server via ajax. The problem is that the file is not stored on server. My java-based backend automatically generates file from request parameters and returns it in response body:
@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.mons.io.IOUtils.copy(fileContent, responseOutputStream);
response.flushBuffer();
} catch (IOException e) {
logger.error("Attempt to download file failed", e);
}
}
So i need to handle it and allow user to download file. My client side contains this:
$.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 returns file, but then nothing happens. What am i doing wrong?
Share Improve this question asked Mar 21, 2016 at 14:42 Everv0idEverv0id 1,9823 gold badges25 silver badges49 bronze badges2 Answers
Reset to default 6Don't make an AJAX call, but rather set the window's href to point to URL for downloading the file. Then change the content type of the response to application/x-download
and set the header of the response to be 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";
}
Also, have a look at this SO post which addresses a similar problem to the one you have.
For those looking a more modern approach, you can use the fetch API
. The following example shows how to download a PDF
file. It is easily done with the following code.
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();
})
I believe this approach to be much easier to understand than other XMLHttpRequest
solutions. Also, it has a similar syntax to the jQuery
approach, without the need to add any additional libraries.
Of course, I would advise checking to which browser you are developing, since this new approach won't work on IE. You can find the full browser patibility list on the following [link][1].
Important: In this example I am sending a JSON request to a server listening on the given url
. This url
must be set, on my example I am assuming you know this part. Also, consider the headers needed for your request to work. Since I am sending a JSON, I must add the Content-Type
header and set it to application/json; charset=utf-8
, as to let the server know the type of request it will receive.
Important: Sending parameters to a 'GET' request using the fetch API
would need to use URLSearchParams
interface.