如何访问public目录外的PDF并在Laravel Blade中正确嵌入?
你遇到的核心问题是没搞清楚Laravel中storage/app/public目录的Web访问逻辑,以及URL生成方式不对。咱们一步步拆解解决:
问题根源
Laravel默认通过符号链接把storage/app/public映射到public/storage,这样Web服务器才能访问到storage目录下的公开文件。你当前写的URLhttp://localhost/projectname/public/storage/app/public/...相当于在符号链接的路径里重复了app/public,导致路径错误,自然无法访问文件。
正确解决方案
1. 确保符号链接已创建
先执行Laravel自带的命令创建符号链接:
php artisan storage:link
这个命令会在public目录下生成一个storage软链,指向storage/app/public目录。如果是共享主机无法执行命令,你可以手动在控制面板创建软链,或者在部署脚本中添加这个命令。
2. 使用正确的URL生成方式
你不需要手动拼接路径,Laravel提供了两种规范的方式生成正确的Web访问URL:
方式一:使用Storage门面的url()方法
因为你的文件存在storage/app/public/media/xxx.pdf,对应的存储路径(相对于storage/app/public)是media/xxx.pdf,直接用Storage::url()生成URL:
<div class="scroller" style="height:500px" data-always-visible="1" data-rail-visible="1" data-rail-color="white" data-handle-color="#A44A1B"> <object data="{{ Storage::url($pdf) }}" type="application/pdf" width="100%" height="100%"></object> </div>
Storage::url($pdf)会自动生成/storage/media/xxx.pdf,对应到Web访问的完整URL就是http://localhost/projectname/storage/media/xxx.pdf,正好是你需要的正确路径。
方式二:使用asset()辅助函数
如果你更习惯用辅助函数,也可以直接拼接storage路径:
<div class="scroller" style="height:500px" data-always-visible="1" data-rail-visible="1" data-rail-color="white" data-handle-color="#A44A1B"> <object data="{{ asset('storage/'.$pdf) }}" type="application/pdf" width="100%" height="100%"></object> </div>
这个效果和Storage::url()一致,因为asset('storage/xxx')会生成http://localhost/projectname/storage/xxx。
为什么之前的方法无效?
storage_path()返回的是服务器上的本地绝对路径(比如/var/www/projectname/storage/app/public/...),不是Web可访问的URL,所以不能直接用在前端。url($path)会基于当前请求的URL拼接,比如当前页面是http://localhost/projectname/dashboard,url('media/xxx.pdf')会生成http://localhost/projectname/media/xxx.pdf,而你的文件并不在这个路径下,所以无效。
内容的提问来源于stack exchange,提问作者MandaCoby




