Laravel – отображать PDF-файл в хранилище без принудительной загрузки?

У меня есть файл PDF, хранящийся в приложении / хранилище /, и я хочу, чтобы прошедшие проверку пользователи могли просматривать этот файл. Я знаю, что могу заставить их загрузить его, используя

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

но мне было интересно, есть ли способ заставить их просматривать файл непосредственно в браузере, например, когда они используют Google Chrome со встроенным средством просмотра PDF. Любая помощь будет оценена!

Обновление за 2017 год

Начиная с Laravel 5.2, зарегистрированного в разделе Другие типы ответов , теперь вы можете использовать вспомогательный файл для отображения файла в браузере пользователя.

 return response()->file($pathToFile); return response()->file($pathToFile, $headers); 

Источник / спасибо ниже ответ

Устаревший ответ с 2014 года

Вам просто нужно отправить содержимое файла в браузер и указать ему тип контента, а не сообщать браузеру о его загрузке.

 $filename = 'test.pdf'; $path = storage_path($filename); return Response::make(file_get_contents($path), 200, [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => 'inline; filename="'.$filename.'"' ]); 

Если вы используете Response::download он автоматически устанавливает в Content-Disposition приложение, которое заставляет браузер загружать его. См. Этот вопрос о различиях между Content-Disposition inline и attachment.

Изменить: согласно запросу в комментариях, я должен указать, что вам нужно будет use Response в начале вашего файла, чтобы использовать Facade.

 use Response; 

Или полностью квалифицированное пространство имен, если Request не сглажено в «Ответный фас» Illuminate.

Начиная с Laravel 5.2 вы можете использовать ответы на файлы
В основном вы можете назвать это следующим образом:

 return response()->file($pathToFile); 

и он будет отображать файлы в формате PDF и изображения, встроенные в браузер.

Ответ Бена Свинберна абсолютно правильный – он заслуживает очков! Для меня, хотя ответ остался немного болтающимся в Laravel 5.1, который заставлял меня исследовать – и в 5.2 (что вдохновило этот ответ) есть новый способ сделать это быстро.

Примечание. Этот ответ содержит подсказки для поддержки имен файлов UTF-8, но рекомендуется учитывать поддержку кросс-платформенной!

В Laravel 5.2 вы можете сделать следующее:

 $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), // eg 'application/pdf', 'text/plain' etc. ]); 

И в Laravel 5.1 вы можете добавить выше метод response()->file() как резерв через поставщика услуг с config/app.php ответа в методе загрузки (обязательно зарегистрируйте его с помощью своего пространства имен в config/app.php если вы сделаете это класс). Содержимое загрузочного метода:

 // 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); // eg '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); }); 

Некоторые из вас не любят Laravel Facades или Helper Methods, но этот выбор за вами. Это должно дать вам указания, если ответ Бен Свинберн не сработает для вас.

Мнение: вы не должны хранить файлы в БД. Тем не менее, этот ответ будет работать, только если вы удалите части фасада Storage , взяв содержимое вместо пути в качестве первого параметра, как с ответом @BenSwinburne.

Я использую Laravel 5.4 и response()->file('path/to/file.ext') чтобы открыть, например, pdf в встроенном режиме в браузерах. Это работает очень хорошо, но когда пользователь хочет сохранить файл, диалог сохранения предлагает последнюю часть URL-адреса в качестве имени файла.

Я уже пытался добавить массив заголовков, как указано в Laravel-docs, но это, похоже, не переопределяет заголовок, заданный с помощью метода file ():

 return response()->file('path/to/file.ext', [ 'Content-Disposition' => 'inline; filename="'. $fileNameFromDb .'"' ]); 

В Laravel 5.5 вы можете просто передать « inline » в качестве параметра удаления функции загрузки:

 return response()->download('/path/to/file.pdf', 'example.pdf', [], 'inline'); 

Ответ Бена Свинберна был настолько полезен.

Код ниже для тех, у кого есть файл PDF в базе данных, такой как я.

 $pdf = DB::table('exportfiles')->select('pdf')->where('user_id', $user_id)->first(); return Response::make(base64_decode( $pdf->pdf), 200, [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => 'inline; filename="'.$filename.'"', ]); 

Где $pdf->pdf – столбец файлов в базе данных.