最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Download of jQuery Ajax request contents is empty - Stack Overflow

programmeradmin6浏览0评论

I have a PHP file that returns output in PDF - Works fine if I access the file directly.

I'd like to retrieve the PDF file through AJAX.

In native Javascript, it works fine:

  var req = new XMLHttpRequest();
  req.open("POST", "./api/pdftest.php?wpid="+wpid, true);
  req.responseType = "blob";
  req.onreadystatechange = function ()
   {
    if (req.readyState === 4 && req.status === 200)
     {
      var blob=req.response;
      var filename = "test.pdf";
      var link = document.createElement('a');
      link.href = window.URL.createObjectURL(blob);
      link.download = "test.pdf";
      link.click();
      var file = new File([blob], filename, { type: 'application/force-download' });
      window.open(URL.createObjectURL(file));
     }
   };
  req.send();

I have a PHP file that returns output in PDF - Works fine if I access the file directly.

I'd like to retrieve the PDF file through AJAX.

In native Javascript, it works fine:

  var req = new XMLHttpRequest();
  req.open("POST", "./api/pdftest.php?wpid="+wpid, true);
  req.responseType = "blob";
  req.onreadystatechange = function ()
   {
    if (req.readyState === 4 && req.status === 200)
     {
      var blob=req.response;
      var filename = "test.pdf";
      var link = document.createElement('a');
      link.href = window.URL.createObjectURL(blob);
      link.download = "test.pdf";
      link.click();
      var file = new File([blob], filename, { type: 'application/force-download' });
      window.open(URL.createObjectURL(file));
     }
   };
  req.send();

But I guess I'd use jQuery to ensure cross browser patibility (although the snippet above works in Edge, Chrome and Firefox on pc, I haven't tested it in other browsers/on other platforms)

So I tried to rewrite the function:

  url='./api/pdftest.php?wpid='+wpid;
  $.ajax(
   {
    url: url,
    method: 'POST',
    responseType: 'blob',
    success: function(data)
     {
      var filename='test.pdf';
      var blob=new Blob([data]);
      var filename = "test.pdf";
      var link = document.createElement('a');
      link.href = window.URL.createObjectURL(blob);
      link.download = "test.pdf";
      link.click();
      var file = new File([blob], filename, { type: 'application/force-download' });
      window.open(URL.createObjectURL(file));
     }
   });

The jQuery equivalent allows me to download a PDF file but … the PDF file is empty.

So I guess I am doing something wrong, probably in the DATA to BLOB conversion. But what? I hope somebody can see what I am doing wrong.

I've been using ages on StackOverflow, read many suggestions - but didn't find any answer. I simply can't see the forest for the trees.

Share Improve this question edited Nov 22, 2018 at 22:07 miken32 42.8k16 gold badges125 silver badges174 bronze badges asked Nov 22, 2018 at 20:52 KairosKairos 1591 silver badge13 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

Looking at the documentation for the jQuery.ajax() function, we see there's no setting called responseType, so you need to use xhrFields to directly set a property of the XHR object. And, since you're only setting the URL and success callback, we can just use the shorter jquery.post() function.

So the data is returned, we make a Blob and then a URL to download it. I'm not on Windows so I can't test if that link I constructed will work as expected, but figured I'd do it the jQuery way.

var url = './api/pdftest.php?wpid=' + wpid;
$.post({
    url: url,
    xhrFields: {responseType: "blob"},
    success: function(data) {
        // don't set the MIME type to pdf or it will display
        var blob = new Blob([data], {type: "application/octet-stream"});
        // build a blob URL
        var bloburl = window.URL.createObjectURL(blob);
        // trigger download for edge
        var link = $("<a>").attr({href: bloburl, download: "test.pdf"}).click();
        // trigger download for other browsers
        window.open(bloburl);
    }
});

As binary data is not possible to retrieve through jQuery.ajax, Native is the only way, at least for now. The following method works in Edge, Firefox, Chrome and Opera - tested on WIndows 10.

    var req = new XMLHttpRequest();
    req.open("POST", "./api/pdftest.php?wpid="+wpid, true);
    req.responseType = "blob";
    req.onreadystatechange = function ()
     {
      if (req.readyState === 4 && req.status === 200)
       {
        var blob=req.response;
        var filename = "test.pdf";
        var link = document.createElement('a');
        link.setAttribute("type", "hidden"); // make it hidden if needed
        link.href = window.URL.createObjectURL(blob);
        link.download = "test.pdf";
        document.body.appendChild(link);
        link.click();
        link.remove();
        var file = new File([blob], filename, { type: 'application/force-download' });
        //window.open(URL.createObjectURL(file));
       }
     };
    req.send();

Probably double!

This is the solution I found thanks to Hisham at Download pdf file using jquery ajax:

First, add the following plugin that can be used to the XHR V2 capabilities missing in JQuery: https://github./acigna/jquery-ajax-native

Then:

   url='./api/pdftest.php?wpid='+wpid;
   $.ajax(
    {
     dataType: 'native',
     url: url,
     xhrFields:
      {
       responseType: 'blob'
      },
     success: function(blob)
      {
       var filename = "test.pdf";
       var link = document.createElement('a');
       link.href = window.URL.createObjectURL(blob);
       link.download = "test.pdf";
       link.click();
       var file = new File([blob], filename, { type: 'application/force-download' });
       window.open(URL.createObjectURL(file));
      }
    });

This seems to be working. Note: the window.open() is to make download possible in Firefox, the link.click() method Works in Edge, Chrome and Opera

Thanks to miken32 for pointing into the right direction.

发布评论

评论列表(0)

  1. 暂无评论