I have a PDF file stored in app/storage/, and I want authenticated users to be able to view this file. I know that I can make them download it using
return
In Laravel 5.5 you can just pass "inline" as the disposition parameter of the download function:
return response()->download('/path/to/file.pdf', 'example.pdf', [], 'inline');
As of laravel 5.5 if the file is stored on a remote storage
return Storage::response($path_to_file);
or if it's locally stored you can also use
return response()->file($path_to_file);
I would recommend using the Storage facade.
Retrieving Files
$contents = Storage::get('file.jpg');
Downloading Files
return Storage::download('file.jpg');
File URLs
$url = Storage::url('file.jpg');
Update for 2017
As of Laravel 5.2 documented under Other response types you can now use the file helper to display a file in the user's browser.
return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
Source/thanks to below answer
Outdated answer from 2014
You just need to send the contents of the file to the browser and tell it the content type rather than tell the browser to download it.
$filename = 'test.pdf';
$path = storage_path($filename);
return Response::make(file_get_contents($path), 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="'.$filename.'"'
]);
If you use Response::download
it automatically sets the Content-Disposition to attachment which causes the browser to download it. See this question for the differences between Content-Disposition inline and attachment.
Edit: As per the request in the comments, I should point out that you'd need to use Response
at the beginning of your file in order to use the Facade.
use Response;
Or the fully qualified namespace if Response
isn't aliased to Illuminate's Response Facade.
Ben Swinburne's answer is absolutely correct - he deserves the points! For me though the answer left be dangling a bit in Laravel 5.1 which made me research — and in 5.2 (which inspired this answer) there's a a new way to do it quickly.
Note: This answer contains hints to support UTF-8 filenames, but it is recommended to take cross platform support into consideration !
In Laravel 5.2 you can now do this:
$pathToFile = '/documents/filename.pdf'; // or txt etc.
// when the file name (display name) is decided by the name in storage,
// remember to make sure your server can store your file name characters in the first place (!)
// then encode to respect RFC 6266 on output through content-disposition
$fileNameFromStorage = rawurlencode(basename($pathToFile));
// otherwise, if the file in storage has a hashed file name (recommended)
// and the display name comes from your DB and will tend to be UTF-8
// encode to respect RFC 6266 on output through content-disposition
$fileNameFromDatabase = rawurlencode('пожалуйста.pdf');
// Storage facade path is relative to the root directory
// Defined as "storage/app" in your configuration by default
// Remember to import Illuminate\Support\Facades\Storage
return response()->file(storage_path($pathToFile), [
'Content-Disposition' => str_replace('%name', $fileNameFromDatabase, "inline; filename=\"%name\"; filename*=utf-8''%name"),
'Content-Type' => Storage::getMimeType($pathToFile), // e.g. 'application/pdf', 'text/plain' etc.
]);
And in Laravel 5.1 you can add above method response()->file()
as a fallback through a Service Provider with a Response Macro in the boot method (make sure to register it using its namespace in config/app.php
if you make it a class). Boot method content:
// Be aware that I excluded the Storage::exists() and / or try{}catch(){}
$factory->macro('file', function ($pathToFile, array $userHeaders = []) use ($factory) {
// Storage facade path is relative to the root directory
// Defined as "storage/app" in your configuration by default
// Remember to import Illuminate\Support\Facades\Storage
$storagePath = str_ireplace('app/', '', $pathToFile); // 'app/' may change if different in your configuration
$fileContents = Storage::get($storagePath);
$fileMimeType = Storage::getMimeType($storagePath); // e.g. 'application/pdf', 'text/plain' etc.
$fileNameFromStorage = basename($pathToFile); // strips the path and returns filename with extension
$headers = array_merge([
'Content-Disposition' => str_replace('%name', $fileNameFromStorage, "inline; filename=\"%name\"; filename*=utf-8''%name"),
'Content-Length' => strlen($fileContents), // mb_strlen() in some cases?
'Content-Type' => $fileMimeType,
], $userHeaders);
return $factory->make($fileContents, 200, $headers);
});
Some of you don't like Laravel Facades or Helper Methods but that choice is yours. This should give you pointers if Ben Swinburne's answer doesn't work for you.
Opinionated note: You shouldn't store files in a DB. Nonetheless, this answer will only work if you remove the Storage
facade parts, taking in the contents instead of the path as the first parameter as with the @BenSwinburne answer.
Since Laravel 5.2 you can use File Responses
Basically you can call it like this:
return response()->file($pathToFile);
and it will display files as PDF and images inline in the browser.