
在使用PHP自定义函数流式传输PDF文件并由PDF.js在浏览器中渲染时,开发者可能会遭遇“Invalid or corrupted PDF file”的间歇性错误。这类问题通常表现为部分文件正常显示,部分间歇性失败,甚至有些文件完全无法加载。尽管文件在本地阅读器(如Acrobat Reader)中表现正常,但PDF.js却报告“Invalid PDF structure”,这往往指向了文件传输或服务器配置层面的问题,而非PDF文件本身的损坏。
当PDF.js在控制台抛出 Invalid or corrupted PDF file. Message: Invalid PDF structure. 错误时,意味着它接收到的PDF数据流不完整或格式不正确。这通常发生在以下场景:
原始问题中,开发者使用了一个名为 smartReadFile 的PHP函数来处理PDF文件的流式传输。该函数旨在支持HTTP Range请求,允许浏览器进行断点续传或请求部分文件内容。
以下是 smartReadFile 函数的核心逻辑:
立即学习“PHP免费学习笔记(深入)”;
function smartReadFile($location, $filename, $mimeType = 'application/octet-stream')
{
if (!file_exists($location))
{
header ("HTTP/1.1 404 Not Found");
return;
}
$size = filesize($location);
$time = date('r', filemtime($location));
$fm = @fopen($location, 'rb');
if (!$fm)
{
header ("HTTP/1.1 505 Internal server error");
return;
}
$begin = 0;
$end = $size - 1;
// 处理HTTP Range请求
if (isset($_SERVER['HTTP_RANGE']))
{
if (preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches))
{
$begin = intval($matches[1]);
if (!empty($matches[2]))
{
$end = intval($matches[2]);
}
}
}
// 设置HTTP状态码和头部
if (isset($_SERVER['HTTP_RANGE']))
{
header('HTTP/1.1 206 Partial Content'); // 部分内容
}
else
{
header('HTTP/1.1 200 OK'); // 完整内容
}
header("Content-Type: $mimeType");
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Accept-Ranges: bytes');
header('Content-Length:' . (($end - $begin) + 1)); // 传输的实际长度
if (isset($_SERVER['HTTP_RANGE']))
{
header("Content-Range: bytes $begin-$end/$size"); // 内容范围
}
if($_REQUEST['SaveAs'] == "1"){
header('Content-Disposition: attachment; filename=' . $filename);
}else{
header("Content-Disposition: inline; filename=\"$filename\""); // 在线显示
}
header("Content-Transfer-Encoding: binary");
header("Last-Modified: $time");
// 实际文件流输出
$cur = $begin;
fseek($fm, $begin, 0);
while(!feof($fm) && $cur <= $end && (connection_status() == 0))
{
print fread($fm, min(1024 * 16, ($end - $cur) + 1)); // 分块读取并输出
$cur += 1024 * 16;
}
fclose($fm); // 关闭文件句柄
}该函数在逻辑上是健全的,它正确处理了HTTP Range请求,并设置了必要的HTTP头部以支持文件流式传输。开发者曾尝试调整 fread 的块大小,但并未解决问题,这进一步暗示问题可能不在PHP代码的直接逻辑错误。
最终,问题的解决指向了一个关键因素:服务器环境。当将同样的代码部署到生产环境的Web服务器上时,问题神秘地消失了。这强烈表明,导致“Invalid or corrupted PDF file”错误的原因在于开发环境(Windows 10上的IIS)与生产环境之间的配置差异。
这种差异可能涉及以下几个方面:
对于在IIS上运行PHP的场景,有几个常见的配置点可能影响大文件或流式传输:
除了IIS,PHP自身的配置也可能影响文件流式传输的稳定性:
当遇到此类问题时,可以采取以下步骤进行诊断和解决:
// 简化版文件传输(不处理Range请求)
function simpleReadFile($location, $filename, $mimeType = 'application/pdf') {
if (!file_exists($location)) {
header("HTTP/1.1 404 Not Found");
return;
}
header("Content-Type: $mimeType");
header("Content-Length: " . filesize($location));
header("Content-Disposition: inline; filename=\"$filename\"");
readfile($location);
}如果简化版工作正常,则问题可能在于 smartReadFile 对HTTP Range请求的处理,或者IIS在处理Range请求时有特殊行为。如果简化版仍有问题,则问题更可能出在IIS或PHP的基本文件传输配置上。
“Invalid or corrupted PDF file”错误在流式传输场景下,往往是服务器环境配置不当的信号。尽管PHP代码本身可能看起来无懈可击,但服务器(如IIS)和PHP运行环境(如FastCGI)的隐式设置却可能在幕后干扰文件传输。
最佳实践:
通过系统地排查服务器配置,并结合对文件流式传输机制的理解,可以有效诊断并解决这类由环境差异引起的间歇性文件损坏问题。
以上就是解决PDF.js间歇性“文件损坏”错误:PHP流式传输与服务器配置深度解析的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号