Reputation: 143
In Laravel 5.7 I'm using a simple route to allow a user to download a local stored csv file.
Route::get('download/{file}', function($file) {
return Storage::disk('s3')->download($file, $file, ['Content-Type: text/csv"']);
})->name('download');
And in my Blade template :
<a href="{{ Route('download', ['file' => 'import.csv']) }}" class="btn btn-primary btn-sm btn-line btn-rect" data-original-title="" title=""> <i class="fa fa-download" aria-hidden="true"></i>
When user clicks on the link, Laravel is finding import.csv file into s3 disk and allow user to download the file but it adds a .txt extension. So the user is downloading import.csv.txt and this file corresponds to import.csv data.
How can I prevent Laravel to add a .txt extension to the CSV file ? I tried return Storage::disk('s3')->download($file, $file);
and return Storage::disk('s3')->download($file);
and same result each time.
Running environment: This is a production server running Apache2 with PHP 7.1 under Debian 9.
EDIT1: I've made the same test on a fresh Laravel 5.7 install, same issue :
Route::get('/', function () {
return Storage::disk('public')->download('import.csv', 'import.csv', ['Content-Type: text/csv"','Content-disposition: attachment;filename=MyVerySpecial.csv']);});
EDIT2: I've added a new test with a controller. Route :
Route::get('test', 'test@test');
Controller test
:
public function test()
{
return Storage::disk('public')->download('import.csv', 'import.csv', ['Content-Type: text/csv"','Content-disposition: attachment;filename=MyVerySpecial.csv']);
}
Exactly the same result
EDIT3: Tested with headers:
['Content-Type: application/octet-stream"','Content-disposition: attachment;filename="MyVerySpecial.csv"']
Same result
EDIT4: Looks to be a server configuration problem as I have this issue with Firefox (last developer edition) and not with IE
Thank you for your help.
EDIT5: I think there is something wrong with Laravel because if I'm creating a php file with:
<?php
$file = "../storage/app/public/import.csv";
header("Content-Description: File Transfer");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . basename($file));
readfile ($file);
exit();
This is working perfectly with Firefox. But if I use a route like
return Storage::disk('public')->download('import.csv', 'import.csv', ['Content-Description: File Transfer','Content-Type: application/octet-stream','Content-Disposition: attachment; filename=/home/webadmin/fresh/storage/app/public/import.csv']);
Well it does not work.
Question: has somebody else tried to reproduce same issue?
Upvotes: 1
Views: 3786
Reputation: 143
The answer of this problem is format used for headers :
Route::get('/', function () {
return Storage::disk('public')->download('import.csv', 'import.csv', ['Content-Description' => 'File Transfer','Content-Type' => 'application/octet-stream','Content-Disposition' => 'attachment; filename=import.csv']);
});
This is a good way how to send headers to download files, tested on Firefox and IE and Chrome
Upvotes: 1
Reputation: 1092
You have to add all these headers :
header('Content-type: application/octet-stream');
header('Content-Length: ' . filesize($data));
header('Content-Disposition: attachment; filename="export.csv"');
Upvotes: 0