【发布时间】: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 服务器配置,而不是文件。