You need to enable JavaScript to run this app. PHP实现的内嵌PDF展示功能在Chrome、Edge中下载报错问题
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现的内嵌PDF展示功能在Chrome、Edge中下载报错问题

问题根因

2023年5月推送的Chromium 113版本(同步覆盖Edge 113+)调整了inline模式PDF资源的下载校验逻辑:当从内嵌预览界面触发下载操作时,浏览器会重新校验资源响应头的完整性,若缺失Content-Length字段,会判定资源不可用,直接抛出网络错误,哪怕缓存中已存在完整的PDF文件内容也不会调用。
Firefox未调整相关逻辑,所以功能正常。

现象解释

  • 文件名识别异常:Chromium 113+之后,下载inline模式的PDF时,不会优先读取Content-Disposition头中的filename参数,默认取当前页面URL的最后一段作为文件名,只有响应头完整符合要求时才会读取自定义文件名。
  • 无新请求产生:预览PDF时资源已完整加载到浏览器缓存,打印和下载操作都会优先调用缓存内容,不会发起新请求。
  • 打印正常但下载失败:打印逻辑直接调用预览界面已加载到内存的渲染后数据,不需要做资源完整性校验;下载逻辑需要走文件保存的安全校验流程,会校验响应头的必填字段是否完整,校验不通过就会报错。

修复方案

在现有响应头中添加Content-Length头即可解决问题,修改后的代码如下:

header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="' . $deliveryPdf->getFilename() . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
// 新增Content-Length头,指定PDF文件的实际大小
header('Content-Length: ' . strlen($deliveryPdf->getData()));
echo $deliveryPdf->getData();

额外注意事项

  • 若服务器对application/pdf类型的响应开启了gzip、Brotli等压缩,需要关闭该类资源的压缩规则,否则实际传输的文件大小和Content-Length指定的大小不一致,仍会触发校验失败。
  • 不要省略输出的PDF内容的长度计算,哪怕PDF内容存在动态生成的场景,也要确保Content-Length的值和实际输出的二进制内容长度完全一致。

内容的提问来源于stack exchange,提问作者Marcel Kirsch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 00:42:02