Downloading a PDF from an HTTP POST call
Here is what I'm trying to accomplish (IE 9+, Chrome, FF, Safari) without the use of JQuery:
Basically I want to get the behavior similar to <a href="test.pdf">
but for a dynamically generated PDF after making a POST call instead of a GET call.
I've tried lots of different things, but they either didn't work cross browser (such as using $window.open() with a blob URL), were blocked by popup blockers (any $window call outside of the click scope), or didn't cause the PDF to be automatically downloaded (any $http POST solution).
I finally found one solution that seems to work which creates a form using javascript and submits it.
var form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', myurl);
var params = {foo: 'bar'};
for(var key in params) {
if(params.hasOwnProperty(key)) {
var hiddenField = document.createElement('input');
hiddenField.setAttribute('type', 'hidden');
hiddenField.setAttribute('name', key);
hiddenField.setAttribute('value', params[key]);
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
form.submit();
This successfully accomplishes the 3 steps above, but now I've run into a new problem. There is no way to determine when the PDF file has been successfully downloaded. This is preventing me from removing the form and from displaying a friendly 'Please wait...' message to the user. There is also the additional problem that submitting the form cancels any outstanding ajax requests as well which isn't optimal.
I have full control over both the server and the client, so what's the best way to fix this? I don't want to have to save the PDF on the server so passing back a url and doing a second GET request from the client won't work in this case. Thanks!
You can make an server response behave as a download by applying some HTTP headers:
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="SOME_NAME.pdf"
Content-Transfer-Encoding: binary
If you're initiating the download through JS only (instead of having the user click a download link), then check out this question for some caveats.
Update: Syntax for POST
Better Update: Form solution with iframe target
You can detect that your server-side script has finished (and subsequently, that the download is ready to begin) by having the form target an iframe. I believe this should also fix the issue of cancelling outstanding Ajax calls, but I'm not certain. Here is the code to do it (just stick this into your code example after the for
loop and before document.body.appendChild(form);
):
var frame = document.createElement('iframe');
frame.setAttribute('id', 'pdfFrame');
frame.onload = function(){
document.body.removeChild(form);
document.body.removeChild(frame);
alert('Download ready!');
}
document.body.appendChild(frame);
form.setAttribute('target', 'pdfFrame');
You can replace my alert
with your code to remove the 'Please wait...'.
上一篇: iFrame的pdf内容在Chrome和Opera中被加载两次
下一篇: 从HTTP POST调用下载PDF