1

We have an interesting way of doing ajax here at work with a custom in house framework, essentially in some javascript function some where I do:

    CT.postSynch('report/index/downloadProjectsInProgress', {}, function(data){
    });

This tells ajax to look for a module called Report, a controller called Index and a action called ajazDownloadProjectInprogress

I wrote a function ajazDownloadProjectInprogress, which all it does is create a simple PDF based on some data I am getting back. in that function I have the following (using DOMPDF) like this:

$dompdf = new DOMPDF();

$content = $this->raw('./report.header','./projectsInProgressReport','./report.footer');

$dompdf->load_html($content);
$dompdf->render();
$dompdf->output();
header('Pragma:');
header('Cache-Control: private,no-cache');
return $dompdf->stream("Structure Report - ProgressReports.pdf", array('Attachment' => 1));

all I'm doing here is grabbing some contents based on the way we render views as either html or raw data, and attempting to stream the pdf back through ajax.

In the above code, where I showed you how we deal with ajax calls, I did:

    CT.postSynch('report/index/downloadProjectsInProgress', {}, function(data){
        return data;
    });

Now the network tab shows me:

%PDF-1.3
1 0 obj
<< /Type /Catalog
/Outlines 2 0 R
/Pages 3 0 R >>
endobj
2 0 obj
<< /Type /Outlines /Count 0 >>
endobj
3 0 obj
<< /Type /Pages
/Kids [6 0 R
]
/Count 1
/Resources <<
/ProcSet 4 0 R
/Font << 
/F1 8 0 R
/F2 9 0 R
>>
/XObject << 
/I1 10 0 R
/I2 11 0 R

Thats just a sample of whats returned back .... If I wasn't doing this through ajax and I just made a direct call to this action an actual PDF would download with my desired contents.

Any one know what your suppose to do to download a PDF through an ajax call? I know ajax it's self will not download the file - but i set up everything such that the function should just start the download process.

LogicLooking
  • 916
  • 1
  • 16
  • 32
  • Why not only `function downloadPdf() { window.location.href = 'report/index/downloadProjectsInProgress?...'; }` ? – Andreas Oct 30 '13 at 17:53
  • because of the way we do ajax that won't work - I didnt create the framework - I just work with it. The way were calling the "controller action" is essentially the same way your doing ... accept our ways converts report to Report and index to index and downloadProjectsInProgress to ajaxDownloadProjectsInProgress – LogicLooking Oct 30 '13 at 17:55
  • 2
    Why Ajax at all for the pdf? Just do the redirect and the download dialog will pop up without leaving the page... – Andreas Oct 30 '13 at 17:56
  • `Any one know what your suppose to do to download a PDF through an ajax call? I know ajax it's self will not download the file` You've answered the question yourself. Create an iframe on the page and set the src to the required url. – Reinstate Monica Cellio Oct 30 '13 at 17:58
  • Sorry, my mistake before, here is the solution i propose: [Dompdf and Ajax Download](https://stackoverflow.com/a/50178700/9742068) – Arturokin12 May 05 '18 at 02:58

1 Answers1

4

Using AJAX to download a PDF would mean, in its simplest form, that you would have to request the binary data of the PDF bit-by-bit. For an example of requesting and then parsing and displaying binary chunks of a PDF file via AJAX, check out Mozilla's PDF.js library in particular their network code.

If instead you simply want to request the PDF from the server and have it download or display in the browser, you should simply get the URL of the PDF in question (which can be your custom controller or something else) and set the window.location to that value. Using the outline in your example, it could be as simple as this:

window.location.href = 'report/index/downloadProjectsInProgress';

You'll want to make sure the server code adds a Content-disposition: attachment; filename=file.pdf header, which will force the window.location change to download the file rather than attempting to display it. Here's a StackOverflow post that describes how to do exactly that.

Community
  • 1
  • 1
Jeff Sisson
  • 1,616
  • 11
  • 22