Laravel - 在存储中显示PDF文件而不强制下载?

时间:2014-09-19 16:18:23

标签: php laravel

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

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

但我想知道是否有办法让他们直接在浏览器中查看文件,例如当他们使用带有内置PDF查看器的Google Chrome时。任何帮助将不胜感激!

10 个答案:

答案 0 :(得分:68)

2017年更新

Other response types下记录的Laravel 5.2开始,您现在可以使用文件助手在用户的浏览器中显示文件。

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

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

Source/thanks to below answer

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内联和附件之间的差异,请参阅this question

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

use Response;

如果Response没有为Illuminate的响应立面设置别名,则为完全限定的命名空间。

答案 1 :(得分:18)

自Laravel 5.2起,您可以使用 File Responses
基本上你可以这样称呼它:

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

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

答案 2 :(得分:8)

Laravel 5.5 中,您只需将“内嵌”作为下载功能的处置参数传递:

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

答案 3 :(得分:4)

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

我已经尝试过添加一个像Laravel-docs中提到的header-array,但是这似乎没有覆盖file()设置的标头 - 方法:

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

答案 4 :(得分:3)

Ben Swinburne's answer绝对正确 - 他应得的分数!对我而言,虽然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中,您可以通过具有a Response Macro in the boot method的服务提供商将上述方法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); }); 中的命名空间进行注册类)。引导方法内容:

Storage

有些人不喜欢Laravel Facades或Helper Methods,但这个选择权属于你。如果Ben Swinburne's answer对你不起作用,这应该会给你指示。

意见提示:您不应该将文件存储在数据库中。尽管如此,只有删除2016-03-16 22:14:01,113] WARN Found a corrupted index file, /kafka_data/kafkain-3655/00000000000000000000.index, deleting and rebuilding index... (kafka.log.Log) [2016-03-16 22:14:01,137] WARN Found a corrupted index file, /kafka_data/kafkain-1172/00000000000000000000.index, deleting and rebuilding index... (kafka.log.Log) [2016-03-16 22:14:01,151] WARN Found a corrupted index file, /kafka_data/kafkain-2362/00000000000000000000.index, deleting and rebuilding index... (kafka.log.Log) [2016-03-16 22:14:01,152] ERROR There was an error in one of the threads during logs loading: java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code (kafka.log.LogManager) [2016-03-16 22:14:01,154] FATAL Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer) java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code at java.io.RandomAccessFile.open0(Native Method) at java.io.RandomAccessFile.open(RandomAccessFile.java:316) at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243) at kafka.log.OffsetIndex$$anonfun$resize$1.apply(OffsetIndex.scala:277) at kafka.log.OffsetIndex$$anonfun$resize$1.apply(OffsetIndex.scala:276) at kafka.utils.CoreUtils$.inLock(CoreUtils.scala:262) at kafka.log.OffsetIndex.resize(OffsetIndex.scala:276) at kafka.log.OffsetIndex$$anonfun$trimToValidSize$1.apply$mcV$sp(OffsetIndex.scala:265) at kafka.log.OffsetIndex$$anonfun$trimToValidSize$1.apply(OffsetIndex.scala:265) at kafka.log.OffsetIndex$$anonfun$trimToValidSize$1.apply(OffsetIndex.scala:265) at kafka.utils.CoreUtils$.inLock(CoreUtils.scala:262) at kafka.log.OffsetIndex.trimToValidSize(OffsetIndex.scala:264) at kafka.log.LogSegment.recover(LogSegment.scala:199) at kafka.log.Log$$anonfun$loadSegments$4.apply(Log.scala:188) at kafka.log.Log$$anonfun$loadSegments$4.apply(Log.scala:160) at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:778) at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33) at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186) at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:777) at kafka.log.Log.loadSegments(Log.scala:160) at kafka.log.Log.<init>(Log.scala:90) at kafka.log.LogManager$$anonfun$loadLogs$2$$anonfun$3$$anonfun$apply$10$$anonfun$apply$1.apply$mcV$sp(LogManager.scala:150) at kafka.utils.CoreUtils$$anon$1.run(CoreUtils.scala:60) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) [2016-03-16 22:14:01,158] INFO shutting down (kafka.server.KafkaServer) 外观部件,将内容而不是路径作为第一个参数,与@BenSwinburne答案一样,此答案才有效。

答案 5 :(得分:2)

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是数据库中的文件列。

答案 6 :(得分:2)

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

return Storage::response($path_to_file);

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

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

我建议使用Storage Facade。

答案 7 :(得分:1)

Laravel 5.6。*

$name = 'file.jpg';

以图片或pdf格式存储

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

下载图片或pdf

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

查看图像或pdf

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

答案 8 :(得分:1)

首先获取文件名,然后在Blade文件中使用anchor(a)标记,如下所示。这也适用于图像视图。

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

答案 9 :(得分:0)

检索文件
chai

下载文件
const chai = require('chai'); const chaiSubset = require('chai-subset'); chai.use(chaiSubset); const expect = chai.expect; expect([ { type: 'text', id: 'name', name: 'name', placeholder: 'John Smith', required: 'required' }, { type: 'email', id: 'email', name: 'email', placeholder: 'example@gmail.com', required: 'required' }, { type: 'submit' } ]).containSubset([{ type: 'text', type: 'email', type: 'submit' }]);

文件网址
$contents = Storage::get('file.jpg');