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:

  • Make an http POST call to my API endpoint with some data
  • Server dynamically generates a PDF and returns the PDF as a binary attachment
  • Browser does default download behavior and downloads the PDF without refreshing the page
  • 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...'.

    链接地址: http://www.djcxy.com/p/36432.html

    上一篇: iFrame的pdf内容在Chrome和Opera中被加载两次

    下一篇: 从HTTP POST调用下载PDF