通过AJAX调用下载文件

I am trying to append some details in to a file and add that for download.

I am using JavaScript and PHP for this purpose.. Clicking download button, it will fire an AJAX request.

$.ajax({
  url:"php/test.php",
  type: 'POST',
  data: { totalQuery : test1, },

  success: function(finalEntityList){
  },
});

Lets assume test.php has a single line code

$html="Test";

Now I want to add this to a file and make it available for download. I've used the code

header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
$output = fopen('php://output', 'w');
fwrite($output, $html);
fclose($output);

But the download will not start automatcially... I've to open the POST request link using firebug so that the download will be initiated.. what could be wrong??

Perhaps what you need to do is simply return the path of the file with your AJAX call and then use JavaScript to "initiate" the download by using one of the following -

  • window.open
  • window.location.href
$.ajax({
  url:"php/test.php",
  type: 'POST',
  dataType: 'json',
  data: { totalQuery : test1, },

  success: function(response){
    // initiate download using direct path to file
    window.location.href = response.URL;
  }
});

Now your test.php file will only need to return the URL path for the download file in a JSON format -

$filename = 'data.csv';
$path = $_SERVER['DOCUMENT_ROOT'].'/downloads/';
echo json_encode(array('URL'=>$path.$filename));

You might consider returning the URL as a raw string - but I feel using JSON might be better because you can easily add additional information in to the response without needing additional parsing functions. All this makes it a more robust choice.

It requires some more parameters and headerinfo:

$file = "data.csv";
$mime_type = "text/csv";
$size = filesize($file);
$name = rawurldecode($name);

@ob_end_clean(); //turn off output buffering to decrease cpu usage

// required for IE, otherwise Content-Disposition may be ignored
if(ini_get('zlib.output_compression'))
    ini_set('zlib.output_compression', 'Off');

header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');

/* The three lines below basically make the
download non-cacheable */
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE']))
{
    list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
    list($range) = explode(",",$range,2);
    list($range, $range_end) = explode("-", $range);
    $range=intval($range);
    if(!$range_end)
    {
        $range_end=$size-1;
    } 
    else
    {
        $range_end=intval($range_end);
    }

    $new_length = $range_end-$range+1;
    header("HTTP/1.1 206 Partial Content");
    header("Content-Length: $new_length");
    header("Content-Range: bytes $range-$range_end/$size");
} 
else
{
    $new_length=$size;
    header("Content-Length: ".$size);
}

/* output the file itself */
$chunksize = 1*(1024*1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($file, 'r'))
{
    if(isset($_SERVER['HTTP_RANGE']))
        fseek($file, $range);

    while(!feof($file) && (!connection_aborted()) && ($bytes_send<$new_length))
    {
        $buffer = fread($file, $chunksize);
        print($buffer); //echo($buffer); // is also possible
        flush();
        $bytes_send += strlen($buffer);
    }
    fclose($file);
} 
else 
    die('Error - can not open file.');