You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中使用mPDF无法inline输出PDF显示乱码问题求助

根本原因

该问题是Laravel响应生命周期和输出控制逻辑冲突导致的:

  • 直接调用$mpdf->Output("test","I")时,mPDF会尝试自行输出响应头和PDF二进制内容,但Laravel默认会在控制器方法执行完成后继续走完后续中间件、响应组装逻辑,自动将响应头覆盖为默认的Content-Type: text/html; charset=UTF-8,同时可能在PDF二进制内容末尾追加额外输出(比如视图残留的空白字符、调试日志、全局后置输出逻辑等),导致浏览器无法识别返回内容为PDF文件,直接将二进制内容作为文本渲染就出现乱码。
  • PHP7.3升级到7.4以及部署方式变更触发问题的原因是:不同版本PHP的输出缓冲(output_buffering)默认配置、服务器虚拟主机的输出规则存在差异,之前的环境下Laravel的后续额外输出被缓冲丢弃,变更后缓冲规则改变,问题就暴露出来。
  • 加die()语句后正常的原理:die()会直接终止PHP进程,打断Laravel的后续生命周期执行,不会出现响应头被覆盖、内容被追加的情况,mPDF输出的完整响应头和PDF内容会原样返回给浏览器,因此可以正常渲染。

无需加die的最优解决方案

按照Laravel的响应规范实现,不要让mPDF直接输出内容,而是获取PDF内容字符串后通过Laravel的响应对象返回:

$mpdf = new \Mpdf\Mpdf();
$mpdf->WriteHTML('Hello World');
// 第二个参数传S表示仅将PDF内容作为字符串返回,不输出任何内容
$pdfContent = $mpdf->Output('', 'S');

// 用Laravel响应返回,自动设置正确的响应头
return response($pdfContent, 200, [
    'Content-Type' => 'application/pdf',
    // inline表示浏览器直接打开,改为attachment则触发下载
    'Content-Disposition' => 'inline; filename="test.pdf"',
]);

该方案完全符合Laravel的编码规范,不会出现响应头被覆盖的问题,兼容性最好。

其他可落地的替代方案

  1. 清空输出缓冲后输出
    如果不想调整原有输出逻辑,可以在调用Output前清空所有已有输出缓冲,避免多余内容污染PDF:
ob_end_clean();
$mpdf->Output("test","I");
// 即使不加die,该方案也能解决大部分场景的问题,如果仍有问题可以再加exit
  1. 排查多余输出逻辑
    检查对应路由的后置中间件、控制器方法末尾、全局公共文件是否有额外输出逻辑(比如echo打印、调试代码、PHP文件末尾多余的?>后空白字符),删除这些多余输出后也可以解决问题。

内容的提问来源于stack exchange,提问作者Daniyal Nasir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 05:24:03