24

I want to use the ajax functionality to download whereby the user will click the download link which will (using ajax and $_GET) access a PHP file which will process the sent $_GET variables and access the correct file for downloading.

I have a few PHP scripts to handle the processing of the $_GET variables which work on their own but when accessed using Ajax, they stop working.

The Ajax/PHP code im using is below:

function ajaxDown(){
$('#downloadmsg').html(
    '<img src=\"media/images/ajaxloader.gif\" width=\"128\" height=\"15\">');
$('#downloadmsg').load(
'media/downloads/downManager.php?file=".$filequery['filename']."&ftype=".$downex[1]."');
}

Please look through my code and help me find what Im doing wrong.

Thanx

miku
  • 181,842
  • 47
  • 306
  • 310
Stanley Ngumo
  • 4,089
  • 8
  • 44
  • 64

2 Answers2

59

I think the problem is that you're trying to load a file result INTO #downloadmsg, which isn't going to work because .load() is only going to load results as HTML...NOT binary data or other encoding.

One approach that might work is creating a hidden iframe in HTML, like this:

<iframe id="secretIFrame" src="" style="display:none; visibility:hidden;"></iframe>

Then, set the attr of the iframe to your querystring:

$("#secretIFrame").attr("src","myphpscript.php?option1=apple&option2=orange");

and then using PHP headers to force the download when the source is set (here's an example of an exporter header set from one of my scripts that uses an octet stream):

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=data.xls ");
header("Content-Transfer-Encoding: binary ");

Hope this helps!

Trafalmadorian
  • 2,498
  • 2
  • 21
  • 13
  • I think this might be the problem let me try your solution. Thanx – Stanley Ngumo Aug 31 '10 at 10:38
  • Why are these solutions so easy once you see them! All I needed was your secret iframe and attr change idea to fix my issue! Thanks! The secret iframe lets the page still be changed while ajax running in the background and still populates the headers! (Which was my problem with a normal AJAX call) Thanks again! – Iron3eagle Nov 27 '12 at 18:50
  • Setting multiple Content-Type headers is a bad practice, header() overrides the previously set values of the same type. See #2 in http://www.media-division.com/the-right-way-to-handle-file-downloads-in-php/ – GeriBoss Aug 23 '14 at 09:32
  • I bereave it is more accurate to remove the two first headers and replace third by this: `header("Cache-Control: must-revalidate, post-check=0, pre-check=0, max-age=0, public");` but perhaps it's dedicated to some buggus browser... which one could it be ;) – Antony Gibbs Nov 21 '14 at 18:41
7

I know I'm late! But I think I have a solution that's a little cleaner without the use of a hidden iframe and you won't even need an ajax request to do it! Using PHP Headers as noted in the accepted answer in a download.php file

<?php
        //download.php 
        /*
          All your verification code will go here
        */      
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
        header("Content-Type: application/force-download");
        header("Content-Type: application/octet-stream");
        header("Content-Type: application/download");
        header("Content-Disposition: attachment;filename=".$_GET['file']);
        header("Content-Transfer-Encoding: binary ");

And on the JS end, simply

function download(filename){
    window.location="http://whateveryoursiteis.com/download.php?file="+filename;
}

Works like a charm :O

ksealey
  • 1,698
  • 1
  • 17
  • 16
  • It shouldn't work with post requests,It's passing the parameter in the URL. In my note above I mentioned you do not use ajax at all to perform the download. – ksealey Sep 22 '16 at 13:43
  • I had to add readfile('path/to-file.jpg') at the end of download.php, otherwise my file was always empty – 00-BBB Sep 16 '19 at 14:18