8

On my HTML page I have made a JQuery ajax request to a php script that should force a download, but nothing is happening?

On my html page (in click event handler for a link)...

var file = "uploads/test.css";
$.ajax(
{
    type      : "POST",
    url       : "utils/Download_File.php",
    data      : {"file":file}
})

And the Download_File.php script looks like this

<?php

Download_File::download();

class Download_File
{
    public static function download()
    {
        $file = $_POST['file'];

        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment');
        readfile('http://localhost/myapp/' . $file);
        exit;
    }
}
?>

But nothing is happening for some reason? I looked at the response headers in firebug and cant see any problems. Im using Xampp. Any help is much appreciated.

Thanks!

Rory
  • 1,805
  • 7
  • 31
  • 45
  • 2
    This is not the way it's done. You need to set `location.href` to the file you want to download, or use an iframe. Check out this question: – Pekka Jan 26 '11 at 21:05
  • possible duplicate of [Ajax File Download using Jquery, PHP](http://stackoverflow.com/questions/3599670/ajax-file-download-using-jquery-php) – Pekka Jan 26 '11 at 21:06

2 Answers2

10

You should specify the Content-Transfer-Encoding. Also, you should specify the filename on your Content-Disposition.

header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="'.$file.'"');
readfile('http://localhost/myapp/'.$file);
exit;

It's important to include double-quotes around the filename as this is required by RFC 2231. Firefox is known to have problems downloading files that have spaces in the file name if the filename is not in quotes.

Also, check to make sure there is no white space after your closing ?>. If even a space exists after the closing PHP tag, the headers won't be sent to the browser.

As a side note, if you have a number of common file types you're going to offer for download, you might consider specifying those MIME types. This provides a better experience for the end user. For example, you could do something like this:

//Handles the MIME type of common files
$extension = explode('.', $file);
$extension = $extension[count($extension)-1];
SWITCH($extension) {
  case 'dmg':
    header('Content-Type: application/octet-stream');
    break;
  case 'exe':
    header('Content-Type: application/exe');
    break;
  case 'pdf':
    header('Content-Type: application/pdf');
    break;
  case 'sit':
    header('Content-Type: application/x-stuffit');
    break;
  case 'zip':
    header('Content-Type: application/zip');
    break;
  default:
    header('Content-Type: application/force-download');
    break;
}
Michael Irigoyen
  • 22,513
  • 17
  • 89
  • 131
  • @Parris Could you share any info on this? I have a download script that does some similar stuff (using cURL instead of `readfile`) and if there's a potential problem, I'd like to address it in my code. :) – Michael Irigoyen Jan 26 '11 at 21:28
  • Yea checkout this question: http://stackoverflow.com/questions/1218925/php-script-to-download-file-not-working-in-ie It identifies the issue, and attempts to solve it. There are also issues around trying to download from https and you are in http... – Parris Jan 26 '11 at 22:00
  • 1
    "Firefox is known to have problems downloading files that have spaces in the file name if the filename is not in quotes." Not just Firefox, either. The command-line wget tool (for Linux/BSD/OSX) is extremely touchy, to the point where you cannot download from VBulletin forum software with the correct filenames. – Powerlord Jan 26 '11 at 22:03
-1

Use document.location.href=URL, instead of ajax..

In my experience ajax causes the problem (download does not work, print contents of the file on browser console).

brooksrelyt
  • 3,925
  • 5
  • 31
  • 54
Latte
  • 1
  • 1