如何在Laravel 8中使用laravel-dompdf正确加载字体与图片资源
1. 修复chroot配置冲突
报错核心原因是控制器配置覆盖了全局chroot权限:你在config/dompdf.php中定义的chroot是项目根目录(可访问所有项目文件),但控制器setOptions方法里又将chroot改为了storage_path('/'),限制dompdf仅能读取storage目录下的文件。而你的字体存放在public/pdf-fonts目录,不在storage路径范围内,自然触发权限拦截。
直接删除控制器setOptions中的'chroot' => storage_path('/')配置项即可。
2. 修正CSS语法与资源路径
语法错误修复
你当前@font-face定义存在语法问题:url('/pdf-fonts/TTNorms-Reg.ttf');末尾多了一个分号,导致后续format("truetype")脱离src属性,dompdf解析会失败,修改后结构如下:
路径替换
dompdf生成PDF时是本地文件读取逻辑,不会走web请求解析相对路径,需要将字体、图片路径替换为绝对本地路径,Blade视图中可直接用public_path辅助函数生成:
@font-face { font-family: 'TTNorms-Reg'; src: url('{{ public_path('pdf-fonts/TTNorms-Reg.eot') }}') format('embedded-opentype'), url('{{ public_path('pdf-fonts/TTNorms-Reg.woff2') }}') format('woff2'), url('{{ public_path('pdf-fonts/TTNorms-Reg.woff') }}') format('woff'), url('{{ public_path('pdf-fonts/TTNorms-Reg.ttf') }}') format('truetype'); }
如果是独立CSS文件无法使用Blade语法,直接写项目绝对路径即可,例如/www/你的项目名/public/pdf-fonts/xxx。
图片资源同理,不要用/images/xxx这类相对web路径,替换为public_path生成的绝对路径或者完整公网URL即可。
3. 检查目录权限
- 给字体缓存目录设置读写权限:执行
chmod -R 755 storage/pdf-assets-cache,确保目录所属用户和web服务器运行用户(如www-data、nginx)一致 - 给字体、图片资源目录设置读权限:执行
chmod -R 755 public/pdf-fonts
4. 可选:调整PDF渲染后端
如果你的服务器没有安装PDFLib扩展,将config/dompdf.php中的"pdf_backend" => "PDFLib"改为"pdf_backend" => "CPDF",使用dompdf自带的渲染后端,避免扩展缺失导致的异常。
5. 生效配置
修改完成后执行php artisan config:clear清理Laravel配置缓存,确保修改的配置生效。
内容的提问来源于stack exchange,提问作者Dave Driesmans

