Spatie/Browsershot在Ubuntu服务器返回二进制数据而非Base64格式PDF
Laravel中Spatie/Browsershot生成Base64 PDF在Ubuntu服务器异常问题
问题描述
本地Windows环境下,使用Spatie/Browsershot生成Base64格式PDF完全正常,但部署到AWS Ubuntu服务器后,返回的不是标准Base64字符串,而是二进制字节对应的ASCII码逗号分隔序列(如37,80,68,70,...)。
本地代码示例
$base64Data = Browsershot::html(view('receipt-pdf', ['data' => $receipt, 'pmData' => $pmData])->render()) ->setNodeBinary("C:\\Program Files\\nodejs\\node") ->setNpmBinary("C:\\Program Files\\nodejs\\npm") ->setChromePath('C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe') ->format('A4') ->base64pdf();
本地输出示例
JVBERi0xLjQKJdPr6eEKMSAwIG9iago8PC9UaXRsZSAoQXFhcmkgLSA3KQovQ3JlYXRvciAoTW96aWxsYS81LjAgXChXaW5kb3dzIE5UIDEwLjA7IFdpbjY0OyB4NjRcKSBBcHBsZVdlYkt...
服务器代码示例
$base64Data = Browsershot::html(view('receipt-pdf', ['data' => $receipt, 'pmData' => $pmData])->render()) ->setChromePath('/usr/bin/google-chrome-stable') ->format('A4') ->base64pdf();
服务器输出示例
37,80,68,70,45,49,46,52,10,37,211,235,233,225,10,49,32,48,32,111,98,106,10,60,60,47,84,105,116,108,......
已排查项
- Chrome执行权限
- 替换为Chromium
- 重新安装Chrome
- 改用
->pdf()生成后再base64_encode()
解决方案
1. 补全Node.js及Puppeteer依赖
Browsershot依赖Node.js和Puppeteer,Ubuntu服务器需先安装:
# 更新源并安装Node.js、npm sudo apt update && sudo apt install nodejs npm -y # 全局安装Puppeteer sudo npm install -g puppeteer
2. 安装Chrome运行必需的系统依赖
Ubuntu下Chrome/Chromium需要额外依赖库才能正常运行:
sudo apt install libnss3 libatk-bridge2.0-0 libdrm-dev libxkbcommon-dev libgbm-dev libasound-dev libatspi2.0-0 libxshmfence-dev -y
3. 修改代码指定Node路径并手动转Base64
明确指定服务器上的Node二进制路径,同时手动将PDF二进制内容转换为Base64(规避base64pdf()方法的系统兼容性问题):
// 生成PDF二进制内容 $pdfBinary = Browsershot::html(view('receipt-pdf', ['data' => $receipt, 'pmData' => $pmData])->render()) ->setChromePath('/usr/bin/google-chrome-stable') ->setNodeBinary('/usr/bin/node') // 指定服务器Node路径 ->format('A4') ->pdf(); // 转换为标准Base64字符串 $base64Data = base64_encode($pdfBinary);
4. 更新Browsershot到最新版本
旧版本可能存在系统兼容问题,执行更新:
composer update spatie/browsershot
5. 显式指定Chrome无头模式
确保Chrome以无头模式启动(默认已开启,可显式声明避免异常):
$pdfBinary = Browsershot::html(...) ->headless() // 其他配置项 ->pdf();
内容的提问来源于stack exchange,提问作者Hussam
相关产品推荐
相关产品推荐

