Skip to content
Advertisement

Download file with ajax and php – readfile not working

I want to save a value to a txt-file and download it to the user.

Right now, the value is being printed into the txt-file correctly, but the readfile function is not triggered, thus no downloading begins.

The php, this code is located on the same page as the ajax call.

<?php 
if (isset($_POST['data']))
{
$handle = fopen("file.txt", "w");
fwrite($handle, $_POST['data']);
fclose($handle);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename('file.txt'));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('file.txt'));
readfile('file.txt');    
exit;   

}

?>

The javascript, there is no url because the data is to be sent to the current page.

 function exportColors() {        
    var exportData = this.dataset.id;

    $.ajax({
            type: "POST",
            data: {data: exportData},
            success: function (data) {
               console.log(data);   
            }   
        });


}

Advertisement

Answer

You need to separate the functionality, that is, post the data to PHP first, save the content of the text file and then, in a second request, let the user download the file. So one (skeleton) approach would be:

JS File:

function exportColors() {        
    var exportData = this.dataset.id;

    $.ajax({
        type: "POST",
        data: {data: exportData},
        success: function (data) {
            // redirect or print out a link
        }   
    });

}

PHP File for the first request (saving the content):

<?php 
if (isset($_POST['data'])) {
    $handle = fopen("file.txt", "w");
    fwrite($handle, $_POST['data']);
    fclose($handle);
    // give back some unique id or the unique filepath
}
?>

PHP File for the second request (be it through clicking on a link or after having been redirected):

// essentially everything that outputs your file
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename('file.txt'));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('file.txt'));
readfile('file.txt');    
exit;   

Comments: Either give back a unique filepath or via a handle through a database (more secure, but more complex as well). Besides, why should the user download the unchanged data he has formerly submitted? Is there more to it than meets the eye?

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement