Reputation: 1128
I want to implement downloading (with AJAX) of uploaded file from server. On the server side I wrote the code
@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 shows response:
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. ***
How to handle and force browser to download file using jQuery?
Upvotes: 14
Views: 65187
Reputation: 78815
Two options are usually used but neither involves AJAX. And jQuery won't be a great help either.
Place an invisible IFrame into your page:
<iframe id="downloadFrame" style="display:none"></iframe>
When the download should start (you didn't mention how it is triggered), use Javascript (and possibly jQuery) to set the URL for the IFrame, which is something like /getInvoice/approvalId/123
in your case:
var iframe = document.getElementById("downloadFrame");
iframe .src = "/getInvoice/approvalId/123";
Setting the IFrame URL should trigger the browser to present the download dialog.
The second option is even simpler. Just navigate to the download URL. Once the browser figures out it's a MIME type that cannot be displayed, it will present a download dialog.
So when the download is triggered, execute the following JavaScript code:
window.location.href = "/getInvoice/approvalId/123";
I'm not sure if all browser will reliably present a download dialog with PDF files. Some browsers might try to display it within the browser itself. The Content-Disposition
HTTP header is helpful but no guarantee.
Upvotes: 34
Reputation: 3868
jQuery-ized answer by Codo:
$('#downloadFrame').remove(); // This shouldn't fail if frame doesn't exist $('body').append('<iframe id="downloadFrame" style="display:none"></iframe>'); $('#downloadFrame').attr('src','/downloadUrlGoesHere');
Upvotes: 4
Reputation: 81
Maybe a better strategy would be to use jQuery to build a new <A> link on the page that'll reference this same URL, and insert this new element at a appropriate place in the DOM. That being done, maybe jQuery can even then click it for the user, initiating the download.
Upvotes: 2