我有一个存储在app/storage /中的PDF文件,我希望经过身份验证的用户能够查看此文件.我知道我可以让他们使用它来下载它
return Response::download($path, $filename, $headers);
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有办法让他们直接在浏览器中查看文件,例如当他们使用带有内置PDF查看器的谷歌浏览器时.任何帮助将不胜感激!
Ben*_*rne 72
2017年更新
从其他响应类型下记录的Laravel 5.2开始,您现在可以使用文件助手在用户的浏览器中显示文件.
return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
Run Code Online (Sandbox Code Playgroud)
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.'"'
]);
Run Code Online (Sandbox Code Playgroud)
如果您使用Response::download它会自动将Content-Disposition设置为附件,这会导致浏览器下载它.有关Content-Disposition内联和附件之间的差异,请参阅此问题.
编辑:根据评论中的请求,我应该指出您需要use Response在文件的开头才能使用Facade.
use Response;
Run Code Online (Sandbox Code Playgroud)
或者,如果Response没有为Illuminate的Response Facade设置别名,则为完全限定的命名空间.
Meg*_*kie 18
从Laravel 5.2开始,您可以使用文件响应
基本上可以像这样调用它:
return response()->file($pathToFile);
Run Code Online (Sandbox Code Playgroud)
它将在浏览器中以内嵌方式显示PDF和图像文件.
小智 12
在Laravel 5.5中,您只需传递" 内联 "作为下载功能的配置参数:
return response()->download('/path/to/file.pdf', 'example.pdf', [], 'inline');
Run Code Online (Sandbox Code Playgroud)
Ben Swinburne 的回答绝对正确——他应得的分数!对我来说,虽然答案在 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.
]);
Run Code Online (Sandbox Code Playgroud)
在 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);
});
Run Code Online (Sandbox Code Playgroud)
你们中的一些人不喜欢 Laravel Facades 或 Helper Methods,但该选择是你的。如果本·斯威本 (Ben Swinburne) 的回答对您不起作用,这应该会给您一些提示。
意见建议:您不应该将文件存储在数据库中。尽管如此,这个答案只有在您删除Storage外观部分时才有效,将内容而不是路径作为第一个参数,就像@BenSwinburne 的答案一样。
小智 5
我正在使用 Laravel 5.4 并response()->file('path/to/file.ext')在浏览器中以内联模式打开例如 pdf。这很有效,但是当用户想要保存文件时,保存对话框会建议将 url 的最后一部分作为文件名。
我已经尝试添加一个像 Laravel-docs 中提到的 headers-array,但这似乎并没有覆盖由 file()-method 设置的标头:
return response()->file('path/to/file.ext', [
'Content-Disposition' => 'inline; filename="'. $fileNameFromDb .'"'
]);
Run Code Online (Sandbox Code Playgroud)
从 laravel 5.5 开始,如果文件存储在远程存储上
return Storage::response($path_to_file);
Run Code Online (Sandbox Code Playgroud)
或者如果它是本地存储的,您也可以使用
return response()->file($path_to_file);
Run Code Online (Sandbox Code Playgroud)
我建议使用 Storage 门面。
| 归档时间: |
|
| 查看次数: |
72143 次 |
| 最近记录: |