У меня есть файл 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
– столбец файлов в базе данных.