我有一个DocumentController.php来处理将文件上传到本地磁盘:
public function store(Request $request)
{
// check to make sure user is an admin
$request->user()->authorizeRoles('admin');
// validate that the document is a pdf and
// that required fields are filled out
$this->validate($request, [
'title' => 'required',
'description' => 'required',
'user_id' => 'required|exists:users,id',
'document_path' => 'required|mimes:pdf'
]);
$file = $request->file('document_path');
$path = $file->store('documents/' . $request->user_id);
$document = Document::create([
'user_id' => $request->user_id,
'title' => $request->title,
'description' => $request->description,
'file_path' => $path
]);
return redirect($document->path());
}
此方法从表单中获取文件,确保它是pdf,然后将文件保存到storage / app / documents / {user_id}。然后,它在数据库中创建一个文档记录,并根据文档ID转发到URL:/ admin / document / {$ document-> id}
该路由被定义为
Route::get('/admin/document/{document}', 'DocumentController@show');
我将控制器中的文件传递给视图:
public function show(Document $document, Request $request)
{
// check to make sure user is an admin
$request->user()->authorizeRoles('admin');
$storagePath = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();
return view('admin.document', compact('document', 'storagePath'));
}
在该页面上,我想显示pdf文档。
resources/views/admin/document.blade.php
@extends('layouts.app')
@section('content')
<div class='container'>
<div class='row'>
<div class='col-sm-2'>
<a href='/admin'>< Back to admin</a>
</div>
<div class='col-sm-8'>
{{ $document }}
<embed src="{{ Storage::url($document->file_path) }}" style="width:600px; height:800px;" frameborder="0">
</div>
</div>
</div>
@endsection
我尝试使用
$storagePath
变量和Storage
方法,但是无法在内部显示pdf文件iframe。使用本地文件存储,如何在浏览器中显示文件?另外,我保护了路由,以便只有管理员才能查看文档页面,但是保护文档本身路径的最佳方法是什么?
#1 楼
如果要保护文件(只有管理员可以访问它们),则需要创建新路由和新DocumentController
方法getDocument
添加新路由
Route::get('documents/pdf-document/{id}', 'DocumentController@getDocument');
在DocumentController中,添加
use Storage;
use Response;
添加新方法,该方法将从存储中读取您的pdf文件并将其返回
public function getDocument($id)
{
$document = Document::findOrFail($id);
$filePath = $document->file_path;
// file not found
if( ! Storage::exists($filePath) ) {
abort(404);
}
$pdfContent = Storage::get($filePath);
// for pdf, it will be 'application/pdf'
$type = Storage::mimeType($filePath);
$fileName = Storage::name($filePath);
return Response::make($pdfContent, 200, [
'Content-Type' => $type,
'Content-Disposition' => 'inline; filename="'.$fileName.'"'
]);
}
在您看来,您可以显示这样的文档
<embed
src="{{ action('DocumentController@getDocument', ['id'=> $document->id]) }}"
style="width:600px; height:800px;"
frameborder="0"
>
#2 楼
来自@ljubadr的Response::make()
的较短版本:return Storage::response($document->file_path)
#3 楼
<embed
src="{{ url('/filepath') }}"
style="width:600px; height:800px;"
frameborder="0">
评论
请在您的代码中添加一些说明-它在哪里使用任何PDF文件?
– Nico Haase
19年4月5日在12:56
评论
$ document-> file_path的值是什么?回答第二个问题-保护文档的安全,您需要将它们移到webroot之外,或使其无法通过Web访问。我建议使用前者,以免将来出现权限错误。然后,您将使用PHP从文件系统读取文件内容,并将其流式传输到浏览器。file_path是我的本地计算机上的路径。为了满足此应用程序的需求,我认为最好将文件存储在S3上。关于将文档存储在webroot之外的好地方