PHP实现浏览器内联PDF预览页面空白的问题排查
问题根因
你的代码存在多处逻辑错误,导致服务端根本没有读取到目标PDF文件,同时错误被手动屏蔽,最终浏览器只能收到空白响应:
- 参数判断逻辑写反:原有代码在
!isset($_GET['docnamepath'])(即参数不存在)的分支里才给$docnamepath赋值,属于完全颠倒的无效逻辑。 - 前端传参多带了冗余单引号:href属性里给PHP输出的路径额外包了一层单引号,最终GET请求拿到的参数值前后自带单引号,比如实际拿到的是
'pdf/xxx.pdf'而非合法路径pdf/xxx.pdf,直接导致路径非法。 - 路径拆分逻辑完全错误:你将传入路径按
/拆分后取了第一个分段$str_arr[0],对于pdf/xxx.pdf这类路径,拆分后第一个分段是目录名pdf(带冗余单引号时是'pdf),后续又拼接了pdf/前缀,最终生成的文件路径是pdf/pdf,和目标PDF文件完全不匹配,readfile读取的是不存在的文件,自然没有内容输出。 - 错误被强制屏蔽:你给
readfile加了@错误抑制符,文件不存在、权限不足等所有报错都被隐藏,看不到任何错误提示,只能看到空白页。 - 额外兼容隐患:如果PHP文件开头存在BOM头、空行,或者在输出PDF头之前有任何内容输出(比如echo的字符、报错信息),会导致返回的PDF内容头部混入非法字符,浏览器无法正常解析PDF也会显示空白。
修复方案
- 修改前端传参代码,去掉多余的单引号,同时对路径做URL编码,兼容带空格、特殊字符的文件名:
<a href="viewimage.php?docnamepath=<?php echo urlencode($scannedfilepath); ?>" class="btn btn-success btn-sm" name="btnview" id="btnview"> <i class="fa-solid fa-thin fa-envelope fa-xs;"></i> View PDF </a>
- 重写后端PHP逻辑,删除无效的路径拆分、错误的参数判断,增加路径安全校验、文件存在校验,清空输出缓冲避免内容污染:
<?php // 所有逻辑放在最开头,确保前面没有任何输出、空行、BOM头 if(!isset($_SESSION)) { session_start(); } // 参数校验,缺失直接返回404 if(!isset($_GET['docnamepath']) || empty($_GET['docnamepath'])) { http_response_code(404); exit("缺少文件参数"); } // 获取参数,过滤目录遍历字符,避免恶意访问服务器其他文件 $docnamepath = $_GET['docnamepath']; $docnamepath = str_replace(['../', '..\\'], '', urldecode($docnamepath)); // 拼接文件绝对路径,避免相对路径匹配错误 $file = __DIR__ . DIRECTORY_SEPARATOR . $docnamepath; // 校验文件存在性 if(!file_exists($file) || !is_file($file)) { http_response_code(404); exit("目标文件不存在,当前查找路径:" . $file); } // 清空所有提前输出的内容,避免污染PDF流 ob_clean(); flush(); // 输出PDF响应头 header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="' . basename($file) . '"'); header('Content-Length: ' . filesize($file)); header('Content-Transfer-Encoding: binary'); header('Accept-Ranges: bytes'); // 输出文件内容 readfile($file); exit; ?>
调试提示
如果修改后仍无法正常显示,先在PHP代码最开头开启错误显示,直接定位具体问题:
error_reporting(E_ALL); ini_set('display_errors', 1);
如果提示文件不存在,核对输出的查找路径和你服务器上PDF的实际存放路径是否一致,调整路径匹配规则即可。
内容的提问来源于stack exchange,提问作者Kym NT
相关产品推荐
相关产品推荐

