Download functionality with Ajax request

Asked

Viewed 1,116 times

3

I’m doing a download function with request via ajax in my application, but it is not working.

If I access the address using the GET method with parameter in the address, the download works perfectly. download.php? option=download

But if I access the file download.php via ajax with the script below the download is not performed.

index php.

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<div class="container">
<form method ="" id="upload_form" >            
    <input id="upload_button" type='button' onclick="download()" name="upload_button" class="btn btn-info" value="Download" />

    <br><br>
</form>
</div>
<br>

<script language="javascript">
    function download(){
        $.ajax({
            type: "GET",
            url: "download.php",
            data:  {
                'opcao': 'download'
            }
        });
    }
</script>

download php.

<?php

$reqmethod = $_SERVER['REQUEST_METHOD'];
$opcao = verificarMetodo($reqmethod);

if($opcao == 'download'){

    $enderecoEntrega        = './';
    $nomeArquivo            = "teste.pdf";

    // Tempo máximo de execução
    // Parâmetro 0 para as conexões lentas
    set_time_limit(0);


    baixarArquivo($enderecoEntrega, $nomeArquivo);
}

function verificarMetodo($reqmethod){
    if($reqmethod == 'POST'){
        $opcao = filter_input(INPUT_POST, "opcao");
    }else{
        $opcao = filter_input(INPUT_GET, "opcao");
    }
    return $opcao;    
}

function baixarArquivo($caminho, $nome){
    $validacao = false;
    $nomeArquivo = "{$nome}";
    $arquivo = "{$caminho}/{$nome}";

    if(!empty($nomeArquivo) && file_exists($arquivo)){
        header("Content-Type: application/pdf");
        header("Content-Disposition: attachment; filename='{$nomeArquivo}'");
        $bool = readfile($arquivo);
    }

    return $bool;
}
?>

I’m doing this feature via ajaxto not have update on the screen while downloading, and although I use only one parameter in the variable data Javascript, I think to use the parameters with file name and address to then be performed a $enderecoEntrega = filter_input(INPUT_GET, "enderecoEntrega"); and $nomeArquivo= filter_input(INPUT_GET, "nomeArquivo"); and get dynamic the address and file of my download.

If you have an alternative way to solve my problem, feel free to post as an answer.

1 answer

7


Ajax doesn’t work that way. The functions performed in PHP only have direct effect on the user if the PHP page opens directly in the browser. How Ajax requests the page on background, so to speak, everything that happens there in PHP stays there. What Ajax does is expect (or not) some response in the form of data (a string or a JSON, for example).

What you would have to do is enable the file to be downloaded by Javascript itself as soon as Ajax receives a response that the request was successful. In the case of jQuery happens through the callback success:

success: function(data){
   // faz alguma coisa
}

Where the value of data is something returned from the requested PHP. Only in your case the data would be empty because PHP is not returning anything (either by a echo or HTML codes). To illustrate, let’s assume that the file download.php have only the code below:

<?
echo "olá";
?>

In this case, the value of data would be olá. In your case, what you could do is return a echo with the file path to be downloaded, for example:

if(!empty($nomeArquivo) && file_exists($arquivo)){
   echo $arquivo;
}

In this case the value of data would be the file path and you can force the download with the Javascript code below, which creates a link element <a> with the attribute download and make an automatic click, forcing the download of the file, all this inside the success::

function download(){
   $.ajax({
      type: "GET",
      url: "download.php",
      data:  {
         'opcao': 'download'
      },
      success: function(data){
         var a = document.createElement("a");
         a.download = data;
         a.href = data;
         a.click();
      }
   });
}

However it is worth noting that the attribute download does not have full support in Microsoft browsers (IE and Edge). In the case of these browsers, instead of opening the dialog to download the file, you will be asked if you want to open or save the file.

Firefox

In Firefox (version 64.0.2) click() only worked if the element is added to the body. Add the element and after the click, remove it:

function download(){
   $.ajax({
      type: "GET",
      url: "download.php",
      data:  {
         'opcao': 'download'
      },
      success: function(data){

         var a = document.createElement("a");
         a.download = data;
         a.href = data;
         document.body.appendChild(a); // adiciona ao body
         a.click();
         a.outerHTML = ''; // remove o elemento

      }
   });
}
  • Have any response with JS-Vanilla?

  • I saw some alternatives on Soen: here and here

  • Dude, the only thing that’s in jQuery is Ajax. It’d just be exchange for XHR. You need to use?

  • I do, but in a project without Jquery (or with a very bizarre access to Jquery, world of GWT). I know Jquery is just syntactic sugar to XHR, but I don’t have the experience to say what each Jquery thing maps to XHR vanilla.

  • 1

    See if it was: https://jsfiddle.net/nf34ahdr/

  • Thanks! It was something like =3 just adapt to GWT and suffer happily

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.