来自 pdf.js 的间歇性“无效或损坏的 PDF 文件”

Posted

技术标签:

【中文标题】来自 pdf.js 的间歇性“无效或损坏的 PDF 文件”【英文标题】:Intermittent "Invalid or corrupted PDF file" from pdf.js 【发布时间】:2022-01-10 04:53:57 【问题描述】:

我正在建立一个私人网站,与我的亲戚分享一些古老的家庭信件。为了防止字母被抓取,我使用了一个名为 smartReadFile 的函数(如下所示)将字母流式传输到浏览器。 (我会给家人一个进入网站的密码。)这些信件是 PDF 文件,是使用扫描仪创建的。

我发现有些字母总是显示得很好,有些显示断断续续,有些则根本不显示。所有这些都可以使用 Acrobat 阅读器正常打开。当字母无法显示时,我会在(Firefox 的)控制台中看到此消息:

Invalid or corrupted PDF file.
PDF.js v2.11.298 (build: d370a281c)
Message: Invalid PDF structure.

我已经使用 Firefox (94.0.2) 和 Chrome (96.0.4664.45) 进行了测试,尽管在任何给定时间,给定的字母可能在其中一个或另一个中表现不同,但我似乎在两者中都存在相同的基本问题。 (刚刚也用 Edge 进行了测试。同样的问题。)

目前,这对我的开发机器来说都是本地的,运行 Windows 10 v. 21H1。安装的 Web 服务器是 IIS。

这是我没有写的函数。 (从我儿子那里得到的,他最初是从别人那里得到的。)

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;
    
    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]);
            
        
    

    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;
    

我的直觉是,这与文件大小或超时或类似的东西有关,但我不知道如何解决它。我尝试减小正在读取和传递的块的大小(通过将函数末尾附近的乘数从 16 更改为 4 或 2),但没有运气。

【问题讨论】:

谢谢。我没有展示它,但是对 smartReadFile 的调用将“application/PDF”作为 $mimeType 传递。用另一个阅读器测试文件的好主意。我也考虑过尝试以某种方式缩小它们,因为有些非常大。 感谢有关 PDF 的建议。我的意图是用一些分辨率来换取尺寸(就像几年前我使用 SnagIt 缩小我以高分辨率扫描的数百张家庭照片的尺寸时所做的那样)。但是,我得出的结论是问题在于我的本地 Web 服务器配置,而不是文件。 【参考方案1】:

在我儿子的建议下,我在生产网络服务器(而不是我的本地安装)上尝试了一个简化版本,问题就消失了。所以我将把它归结为我的 IIS 安装中的一些我不需要弄清楚的设置,然后继续完成这个项目。

【讨论】:

以上是关于来自 pdf.js 的间歇性“无效或损坏的 PDF 文件”的主要内容,如果未能解决你的问题,请参考以下文章

来自 WCF REST 服务的 Azure 缓存间歇性响应时间

PDF.js 插入图像

pdf.js相关问题整理

S3 文件的 PDF.js CORS 问题

处理来自 selenium 的自刷新页面

VBA 间歇性 ByRef 错误 - 格式函数