Hafid Denguir
Hafid Denguir

Reputation: 952

symfony2 how to force download in Ajax return json datatype

I am trying to make a link to download a file with symfony2.

It does download a file, but it's not work iin chrome . I don't know how to make it work. Does anybody know how to do?

JQuery Code :

$.ajax({
        url: url,
        type: "POST",
        data: {id : id},
        dataType: "json",
        success: function(resp){
            console.log(resp);
        },
        error: function(x, y, z){
            //console.log( x ); 
        }
});

PHP Code in controller :

$response = new Response();

// Set headers
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '"');
$response->headers->set('Content-length', filesize($filename));

// Send headers before outputting anything
$response->sendHeaders();

$response->setContent(file_get_contents($filename));

Upvotes: 1

Views: 3662

Answers (1)

Bastien Libersa
Bastien Libersa

Reputation: 690

There's a solution that is compatible with all browsers: do not use Ajax to do this. Instead, write a simple "location.href" instruction like so:

$("#download").on('click', function() {
    location.href = "{{ path('download_file', { 'fileId': file.id }) }}";
});

And your Symfony controller could be (for example):

/**
 * @Route("/download_file/{fileId}", name="download_file")
 */
public function downloadFileAction($fileId)
{
    $filename = ....

    $response = new Response();
    $response->headers->set('Content-Type', mime_content_type($filename));
    $response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '"');
    $response->headers->set('Content-Length', filesize($filename));
    $response->headers->set('Pragma', "no-cache");
    $response->headers->set('Expires', "0");
    $response->headers->set('Content-Transfer-Encoding', "binary");

    $response->sendHeaders();

    $response->setContent(readfile('LOCATION_OF_FILE/'.$filename));

    return $response; 
}

Your file will be automatically downloaded and your user will stay on the current page, which is I think what you expect.

Upvotes: 1

Related Questions