Mr.t
Mr.t

Reputation: 91

How to download file from storage?

I'm using Laravel's file storage system and I'm trying to trigger a download response to download my files through the browser, but it cant find the correct file instead it downloads my file page view script. I have a storage link set up as well.

Any suggestions would be appreciated.

File.blade.php

 @extends('layouts.app')

 @section('content')


 <div class="container">
  <form action="{{route('upload')}}" method="POST" 
  enctype="multipart/form-data" name="formName"> 
{{csrf_field() }}
     <input type="file" name="file">
     <input type="submit" class="btn" name="submit">
</form>
<div class="row">
@foreach($files as $file)
   <a href="{{route('download',$file)}}" download="{{$file->name}}"> 
   {{$file->name}}</a>

 </div>
 </div>

 @endsection

Download function

public function download($file){


    return response()->download(storage_path('/storage/app/files/'.$file));
 }

file routes

  Route::get('files', 'FileController@index')->name('upload');
  Route::post('files', 'FileController@store');
  Route::get('files/{file}', 'FileController@download')->name('download');

Upvotes: 6

Views: 21021

Answers (4)

Strabek
Strabek

Reputation: 2511

I use Laravel v9, and I use Storage to download a file from local storage (visibility = private):

public function download(): StreamedResponse
{
    return Storage::disk('disk_name')->download(
        $pathToAFile,
        $downloadedFileName
    );
}

After clicking a link, a file is downloaded.

Upvotes: 1

Abdur Rahman IsHa
Abdur Rahman IsHa

Reputation: 1

public function jpg_download($id)
{
    if (auth()->user()->download_count < 5) {

        auth()->user()->increment('download_count');
        $data = DB::table('products')->where('id', $id)->first();
        $path = public_path('/storage/item/jpg/' . $data->jpg);
        return response()->download($path);
    }
    dd('Next Day Download');
}

Upvotes: 0

Thungdemo
Thungdemo

Reputation: 136

I think you are passing the file object instead of the filename to your download route. Try

 @extends('layouts.app')

 @section('content')


 <div class="container">
  <form action="{{route('upload')}}" method="POST" 
  enctype="multipart/form-data" name="formName"> 
{{csrf_field() }}
     <input type="file" name="file">
     <input type="submit" class="btn" name="submit">
</form>
<div class="row">
@foreach($files as $file)
   <a href="{{route('download',$file->name)}}" download> 
   {{$file->name}}</a>

 </div>
 </div>

 @endsection

Try replacing {{route('download',$file)}} with {{route('download',$file->name)}}. Also try replacing the download controller with this code

public function download($file){
    return response()->download(storage_path('app/files/'.$file));
 }

Upvotes: 1

porloscerros Ψ
porloscerros Ψ

Reputation: 5078

Remove this download="{{$file->name}}" from the link.
You can add download as html attribute:

<a href="{!! route('download', $file->name) !!}" download>{{ $file->name }}</a>

But you don't need it in this case, use just:

<a href="{!! route('download', $file->name) !!}">{{$file->name}}</a>

The response()->download() method in your controller will generate a response that forces the browser to download the file at the given path. So make sure your path i correct.
If your file is in your-project-root-path/storage/app/files/, you can use:

return response()->download(storage_path('/app/files/'. $file));

If your file is in your-project-root-path/storage/storage/app/files/, use:

return response()->download(storage_path('/storage/app/files/'. $file));

Upvotes: 7

Related Questions