wiltomap
wiltomap

Reputation: 4223

Impossible to fire CSV file download from Ajax query

I want to fire a download window from an Ajax query.

The Ajax query is launched when I click on a button on my page.

Here is the Ajax query (function called on click on the button):

function exportDetailOuvrage(idData){

    $.ajax({
        url : 'ouvrage.php',
        type : 'POST',
        data : { typeOuvrage : idData },
        success : function (data){
            $('body').append(data);
        }
    });
}

Here is the PHP code to generate the CSV:

<?php

$csv = "Town;Name;Code\r\n" ;

foreach($result as $row){

    $csv .= $row['town'].";".$row['name'].";".$row['code']."\r\n" ;

}

header("Content-Type: text/csv; charset=utf-8");
header("Content-Disposition: attachment; filename=data.csv");

echo $csv;

?>

In the PHP code, $result is an array built on a SQL query in a database.

The CSV string is generated as wanted, the server answer is 200 (no errors using firebug). I have checked the sent parameters and the CSV string returned: everyting is OK.

The only issue is that no download window appears and no data.csv file is saved...

I was wondering if my Ajax code, especially the content of success parameter is good. I don't know what to put exactly inside this parameter.


EDIT :

According to @MonkeyZeus answer and comments, here is the content of my gimme_file.php:

<?php

    session_start();

    header("Content-Type: text/csv; charset=utf-8");
    header("Content-Disposition: attachment; filename=data.csv");
    readfile($_SESSION['I_CAN_DOWNLOAD_ONLY_THIS']);

    exit;

?>

I get the following error message inside the data.csv downloaded file:

<br />
<b>Notice</b>:  Undefined index: I_CAN_DOWNLOAD_ONLY_THIS in <b>D:\STAT\modele\gimme_file.php</b> on line <b>7</b><br />
<br />
<b>Warning</b>:  readfile(): Filename cannot be empty in <b>D:\STAT\modele\gimme_file.php</b> on line <b>7</b><br />

Upvotes: 0

Views: 1782

Answers (1)

MonkeyZeus
MonkeyZeus

Reputation: 20737

Javascript (jQuery) can absolutely NOT trigger a file download natively; it would be a gigantic security issue.

What you must do is the following:

  1. Call the CSV generator
  2. Save the CSV to the server with a unique name
  3. Pass this unique name to your success: callback
  4. Use window.location to redirect the browser to the CSV file

My apologies if my post is very terse but I just do not want you to chase your tail for hours trying to achieve something that is fundamentally blocked by web browsers.


jQuery

function exportDetailOuvrage(idData){

    $.ajax({
        url : 'ouvrage.php',
        type : 'POST',
        data : { typeOuvrage : idData },
        success : function (data){
            window.location = 'http://www.mywebsite.com/gimme_file.php';
        }
    });
}

ouvrage.php

<?php

session_start();

$csv = "Town;Name;Code\r\n" ;

foreach($result as $row){

    $csv .= $row['town'].";".$row['name'].";".$row['code']."\r\n" ;

}

$filename = 'ouvrage_'.uniqid('', TRUE).'.csv';

file_put_contents($filename, $csv);

$_SESSION['I_CAN_DOWNLOAD_ONLY_THIS'] = $filename;

?>

gimme_file.php

<?php
session_start();

header("Content-Type: text/csv; charset=utf-8");
header("Content-Disposition: attachment; filename=data.csv");
readfile($_SESSION['I_CAN_DOWNLOAD_ONLY_THIS']);
exit;

?>

Upvotes: 3

Related Questions