Laravel-在存储中显示PDF文件,而无需强制下载


Laravel - display a PDF file in storage without forcing download?

我有一个PDF文件存储在app/storage/中,我希望经过身份验证的用户能够查看此文件。我知道我可以让他们使用

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

但我想知道是否有办法让他们直接在浏览器中查看文件,例如当他们使用带有内置 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它会自动将内容处置设置为附件,从而导致浏览器下载它。有关内联内容处置和附件之间的区别,请参阅此问题。

编辑:根据评论中的要求,我应该指出,您需要在文件的开头use Response才能使用外观。

use Response;

或者完全限定的命名空间(如果Response没有别名到 Illum 的响应外观。

从 Laravel 5.2 开始,您可以使用文件响应
基本上你可以这样称呼它:

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

它将在浏览器中以 PDF 格式显示文件和内联图像。

Laravel 5.5 中,您只需传递">inline"作为下载函数的处置参数:

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

从 laravel 5.5 开始,如果文件存储在远程存储中

return Storage::response($path_to_file);

或者,如果它是本地存储的,您也可以使用

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

我建议使用存储立面。

本·

斯温伯恩的回答是绝对正确的——他配得上积分!对我来说,虽然答案在 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), // e.g. 'application/pdf', 'text/plain' etc.
]);

在 Laravel 5.1 中,您可以通过在引导方法中使用响应宏的服务提供商添加上述方法response()->file()作为回退(如果您将其设为类,请确保在 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); // 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);
});

你们中的一些人不喜欢Laravel外墙或助手方法,但这个选择是你的。如果本·斯温伯恩的答案不适合你,这应该给你指点。

固执己见的注释:您不应该将文件存储在数据库中。尽管如此,仅当您删除Storage立面部分时,此答案才有效,并且像@BenSwinburne答案一样将内容而不是路径作为第一个参数。

我正在使用Laravel 5.4和response()->file('path/to/file.ext')在浏览器中以内联模式打开例如pdf。这很好用,但是当用户想要保存文件时,保存对话框会建议将 url 的最后一部分作为文件名。

我已经尝试添加 Laravel-文档中提到的标头数组,但这似乎并没有覆盖 file((-method设置的标头:

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

首先检索文件名,然后在刀片文件中使用 anchor(a( 标记,如下所示。这也适用于图像视图。

<a href="{{ asset('storage/admission-document-uploads/' . $filename)}}" target="_blank"> view Pdf </a>;

Laravel 5.6.*

$name = 'file.jpg';

存储在图像或 PDF 上

$file->storeAs('public/', $name );

下载图像或 PDF

return response()->download($name);

查看图像或 PDF

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

Ben Swinburne的回答非常有帮助。

下面的代码适用于像我这样在数据库中拥有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是数据库中的文件列。

检索文件
$contents = Storage::get('file.jpg');

正在下载文件
return Storage::download('file.jpg');

文件 URL
$url = Storage::url('file.jpg');

您可以尝试此操作,它将在浏览器中打开pdf或其他资产作为选项卡:

<a href="{{ URL::asset('/path/to/your/file.pdf') }}">Link to you doc</a>

使用锚标记意味着它的行为链接任何其他链接。