Rohan Rohan - 27 days ago 12
PHP Question

How to force download files using Laravel 5?

Yes I have read the documentation. :)

My controller method looks like:

public function download($id)
{
$file = $this->fileRepo->find($id);

$randomDir = md5(time() . $file->id . $file->user->id . str_random());

mkdir(public_path() . '/files/' . $randomDir);

$path = public_path() . '/files/' . $randomDir . '/' . $file->name;

file_put_contents($path, base64_decode($file->data));

header('Content-Description: File Transfer');

return response()->download($path);
}


It takes the BLOB from the database, converts it, saves it temporarily on the filesystem in the public folder under a random folder and then serves the download. The headers in postman show up like so:

Accept-Ranges → bytes
Access-Control-Allow-Headers → Content-Type, Accept, Authorization, X-Requested-With, Application
Access-Control-Allow-Methods → POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin → *
Cache-Control → public
Connection → close
Content-Description → File Transfer
Content-Disposition → attachment; filename="taxonomy.odt"
Content-Length → 43626
Content-Type → application/vnd.oasis.opendocument.text
Date → Wed, 18 Nov 2015 11:38:36 GMT
Host → localhost:8000
Last-Modified → Wed, 18 Nov 2015 11:38:36 GMT
X-Powered-By → PHP/5.5.9-1ubuntu4.14


I guess all the headers are set correct depending on what kind of file is being served (odt in this case).

I tried running this script to test the API for download:

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

<script>
$.ajax({
url: "http://localhost:8000/api/files/53/download",
method : "get",
data : {
},
headers: {
Authorization: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImNhcnBhcnRzIiwic3ViIjoiMSIsImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDAwXC9hcGlcL2F1dGhlbnRpY2F0ZSIsImlhdCI6IjE0NDc4MjQwOTEiLCJleHAiOiIxNDQ3ODc4MDkxIiwibmJmIjoiMTQ0NzgyNDA5MSIsImp0aSI6ImI2MzRiZDY4ZTMyNjA3OWE3OGYzNzlhNGVkYjJlYzRhIn0.oLF71WsOkl5kDdnRBkpKSbDHD_kCk45yONuB_TiIKxc'
}
})
.done(function (data) {
// console.log(data);
})
.fail(function (jqXHR, textStatus) {
alert("error: " + textStatus);
});
</script>


I can uncomment the
.done
closure and it logs the file just fine. I have tried all sorts of files: json, text, odt and so on. JSON shows up just fine, so does text. The odt file has a lot of weird characters which is obvious why. But the browser just won't popup the download window. Why? What am I doing wrong?

PS: I also made sure that
fileinfo
extension is enabled. :)

Answer

No ajax request is needed. Just click on this link:

<a href="http://localhost:8000/api/files/53/download">Download</a>

The page will not reload by clicking this link. Just try it.

Comments