Blorange2
Blorange2

Reputation: 31

Laravel Response::download() function image issue

I'm using Laravel 5. I am creating a photo gallery of sorts. When you click on an image I use

Response::download($path,$filename,$headers);

To initiate a download of the file.

Below is my code:

Route

Route::get('test/{filename}', 'ImageController@getDownload');

When the user goes to test/example.png, it runs the getDownload function

Controller

public function getDownload($filename){
    // Define the path and the extension
    $file = public_path() . "/uploads/" . $filename;
    $ext = pathinfo($filename, PATHINFO_EXTENSION);

    if($ext == 'png' || 'PNG'){
      $headers = array(
          'Content-Type:image/png',
        );
    }

    else if($ext == 'jpg' || 'jpeg' || 'JPEG' || 'JPG'){
      $headers = array(
          'Content-Type:image/jpeg',
        );
      }

      else if($ext == 'gif' || 'GIF'){
      $headers = array(
          'Content-Type:image/gif',
        );
      }

      $response = Response::download($file, $filename, $headers);

      return $response;

}

In this function I declare the path to my files and set up the download.

View

@foreach ($fileList as $uploadedFiles)
    <div class='img'>
    <a href="test/{{$uploadedFiles}}"/><img src="{{ $uploadsFolder}}/{{   $uploadedFiles }}"/></a>
    </div>  

@endforeach

In my view I use a loop to get the filenames, then create a link that goes to test/$filename which invokes the method in the Controller.

The problem

Using this approach seems to work as I can download docx files, PDFs, txt files, csv files and more. However, when an image is downloaded, when I open it I get "The image cannot be displayed".

In my uploads folder I have an image named cake.JPG.

When I download this the Request headers are as follows:

The Response headers are as follows:

With images in particular have I set up the headers incorrectly?

Thank you in advance.

Upvotes: 3

Views: 5031

Answers (1)

Jan Willem
Jan Willem

Reputation: 1320

When processing images in this context, you have two options.

1. Download the image

This means, the file will be prompted to download. In this case, you should always set this headers (in this case, the mimetype of the file itself is not important):

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="somefilename.someextension"

This is the same for any type of file, it's just the generic way to force download. Make sure the filename is set accordingly.

Note: this is just to explain. Laravel will build these headers itself when using download(). Just make sure you don't include a Content-type header using this method.

2. Display the image

In this case, the image will be shown as a regular image. Here, you should not set the Content-Disposition header, but only the Content-type header:

Content-Type: image/jpeg

This should be set according to the corresponding mimetype of the image.

In Laravel:

You should use something like the following instead of the download() method:

$response = Response::make($file, 200)->withHeaders($headers);

Upvotes: 0

Related Questions