JWeyh JWeyh - 1 year ago 244
Javascript Question

PDF File download from AJAX Post success callback

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 compatible 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.

url: myUrl,
data: params,
success: function(result,status,jqhxr) {
var blob=new Blob([result]);
var link=document.createElement('a');

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.


Answer Source

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){
        return navigator.msSaveOrOpenBlob(blob, filename)

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

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'))

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');

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)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download