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

javascript - PDF File download from AJAX Post success callback - Stack Overflow

programmeradmin5浏览0评论

When I try to link to a data-generated file that I've set up to be rendered as a PDF document, this works to open a PDF document in a new window, but only for small sets of data:

window.open(myUrl + params, "_blank", "menubar=no,status=no");

I need it to work for something like this so I can make my PDF patible with larger data sets. I tried passing the params in the data section of the ajax request but it doesn't work for PDF documents only. It works for Word and Excel documents. When I try the same thing as a PDF, it returns a download to a broken PDF object.

$.ajax({
   type:"POST",
   async:true,
   url: myUrl,
   data: params,
   success: function(result,status,jqhxr) {                 
         var blob=new Blob([result]);
       var link=document.createElement('a');
       link.setAttribute('target','_blank');
       link.href=window.URL.createObjectURL(blob);
       link.download="PreviewProposalAsPdf.pdf";
       link.click();                    
   }
});

What do I need to do to get this to render a PDF correctly? Ideally I'd like to navigate directly to the PDF page in a new window, but I will settle for a clickable file download. Please post the full solution directly if possible. I've spent a ton of time on this and my time is now running short.

I looked for the solution on other questions but none of the solutions worked. In some cases, what I'm already trying was posted as a solution. Please help.

Thanks

When I try to link to a data-generated file that I've set up to be rendered as a PDF document, this works to open a PDF document in a new window, but only for small sets of data:

window.open(myUrl + params, "_blank", "menubar=no,status=no");

I need it to work for something like this so I can make my PDF patible with larger data sets. I tried passing the params in the data section of the ajax request but it doesn't work for PDF documents only. It works for Word and Excel documents. When I try the same thing as a PDF, it returns a download to a broken PDF object.

$.ajax({
   type:"POST",
   async:true,
   url: myUrl,
   data: params,
   success: function(result,status,jqhxr) {                 
         var blob=new Blob([result]);
       var link=document.createElement('a');
       link.setAttribute('target','_blank');
       link.href=window.URL.createObjectURL(blob);
       link.download="PreviewProposalAsPdf.pdf";
       link.click();                    
   }
});

What do I need to do to get this to render a PDF correctly? Ideally I'd like to navigate directly to the PDF page in a new window, but I will settle for a clickable file download. Please post the full solution directly if possible. I've spent a ton of time on this and my time is now running short.

I looked for the solution on other questions but none of the solutions worked. In some cases, what I'm already trying was posted as a solution. Please help.

Thanks

Share Improve this question asked Sep 14, 2016 at 19:16 JWeyhJWeyh 231 silver badge4 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

The result you get back from using jQuery ajax is plain text and can lead to "out of range" for downloading binary as text and not as arrayBuffer or blob. jQuery don't support responseType in any way (that i know of)

So you need to rely on xhr or fetch to get it as a blob to get the content right. Otherwise you will get corrupt data

Here is an example of using the new fetch api and FileSaver

function saveAs(blob, filename){
    if(navigator.msSaveOrOpenBlob)
        return navigator.msSaveOrOpenBlob(blob, filename)

    var link = document.createElement('a')
    link.href = window.URL.createObjectURL(blob)
    link.download = filename
    link.click()
}

fetch(myUrl, {
    method: 'post', 
    body: JSON.stringify(params)
    headers: {
        'Content-Type': 'application/json;charset=UTF-8'
    }
})
.then(res => res.blob())
.then(blob => saveAs(blob, 'PreviewProposalAsPdf.pdf'))


// EXAMPLE USING XHR
var req = new XMLHttpRequest
req.open('GET', myUrl, true)
req.responseType = 'blob'
req.onload = function() {
    saveAs(res.response, 'Dossier_' + new Date() + '.pdf')
}
req.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
req.send(JSON.stringify(params))

But ofc, there is more wider support if you use xhr + responseType = blob

The best thing you can do is just send content-disposition header and make a attachment - but then you can not use ajax... need to submit form (could be from iframe)

Another solution using $.ajax & FileSaver

I think the xhrFields should be the answer you look for...

$.ajax({
    type: "POST",
    url: "your-url/to/pdf/response",
    data: params,
    xhrFields: {
        responseType: 'blob'  // without this, you will get blank pdf!
    },
}).done( function(res) {
    blob = new Blob([res], { type: 'application/pdf' })
    saveAs(blob, "response.pdf")
}).fail( function() {
    alert("Error! Please try again later...");
});

This is the correct answer, without using the SaveAs function:

var req = new XMLHttpRequest();
req.open("POST", myUrl, true);

req.responseType = "blob";

req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.send(data);

req.onreadystatechange = function() {//Call a function when the state changes.
    if(req.readyState == 4 && req.status == 200) {
        console.log(req.responseText);
    }
}

req.onload = function (event) {
   var blob = req.response;
   console.log(blob.size);
   var link=document.createElement('a');
   link.href=window.URL.createObjectURL(blob);
   link.download="Dossier_" + new Date() + ".pdf";
   link.click();
};

Ultimately it solved my problem. Thank you, Endless.

发布评论

评论列表(0)

  1. 暂无评论