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.commons.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?
Don'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 compatibility 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With