Yi2 Download File Using SendFile()

Tags: , , ,



I am attempting to use the built in function sendFile() provided by Yii2 to allow users to download files. This will not, however, actually download the file.

Below is my ajax code

 $.ajax({
     url: 'https://'+window.location.hostname+'/download',
     dataType: "json",
     type: 'POST',
     data: {name: name},
   })

Server side code

  $filename = "test.txt";
  $path = Yii::getAlias('@webroot')."/uploads/test.txt";
  Yii::$app->response->sendFile($path, $filename)->send();



  //I've also tried variations of the file path and name. E.G:
  $filename = "test.txt";
  $path = Yii::getAlias('@webroot')."/uploads";

The code provided above is what I am currently using to download the file. When a user clicks on a download icon, an Ajax call is made to the action containing the logic above, thus sending that file to the user’s browser.

When the Ajax call is made, the server returns 200 but doesn’t actually download the file. Instead, in the response is the content of the file being requested. For instance, if the user requests a file containing the text 'Hello there!', when the Ajax call is finished, nothing will be downloaded but the server response (as seen through FireFox dev tools) shows 'Hello there!'.

Is there any reason why the file itself isn’t downloading?

If I just navigate to the url (lets say its localhost/downloadFile) in another tab, the action is called, the download dialogue opens, and I can download the file.

Answer

  1. First thing you have to return the statement, an there isnt any use of calling send() after the sendFile() if you are returning it from the controller action, just keep it like below

    return Yii::$app->response->sendFile($path, $filename);
    
  2. Ajax isnt for file downloads you should either create a popup window or simply use

    window.location.assign('https://'+window.location.hostname+'/download/'+name);
    

And you will see that the page wont change that you are currently on and the file download dialog will be triggered.



Source: stackoverflow