Прерывистый «Недопустимый или поврежденный PDF-файл» из pdf.js

#php #pdf.js

#php #pdf.js

Вопрос:

Я создаю частный веб-сайт, чтобы поделиться некоторыми старыми семейными письмами со своими родственниками. Чтобы предотвратить обход писем, я использую функцию smartReadFile (показана ниже) для потоковой передачи писем в браузер. (Я дам семье пароль для входа на сайт.) Письма представляют собой PDF-файлы, созданные с помощью сканера.

Я нахожу, что некоторые буквы всегда отображаются просто отлично, некоторые отображаются с перерывами, а некоторые вообще не отображаются. Все они прекрасно открываются с помощью Acrobat reader. Когда письмо не отображается, я вижу это сообщение в консоли (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. Установленным веб-сервером является 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) amp;amp; $cur lt;= $end amp;amp; (connection_status() == 0))  {  print fread($fm, min(1024 * 16, ($end - $cur)   1));  $cur  = 1024 * 16;  } }  

Мой инстинкт подсказывает, что речь идет о размере файла, таймауте или чем-то в этом роде, но я не знаю, как это исправить. Я попытался уменьшить размер фрагментов, которые я читаю и передаю (изменив множитель ближе к концу функции с 16 на 4 или 2), но безуспешно.

Комментарии:

1. Спасибо. Я этого не показывал, но вызов smartReadFile передает «приложение/PDF» как тип $mimeType. Хорошая идея проверить файлы с помощью другого считывателя. Я также подумывал о том, чтобы попытаться каким-то образом уменьшить их, потому что некоторые из них довольно большие.

2. Спасибо за совет по поводу PDF-файлов. Мое намерение состояло в том, чтобы обменять некоторое разрешение на размер (как я сделал много лет назад, когда использовал SnagIt, чтобы уменьшить размер сотен семейных фотографий, которые я сканировал с высоким разрешением). Однако я пришел к выводу, что проблема заключается в конфигурации моего локального веб-сервера, а не в файлах.

Ответ №1:

По совету моего сына я попробовал упрощенную версию на производственном веб-сервере (а не на моей локальной установке), и проблема исчезла. Поэтому я сведу это к некоторым настройкам в моей установке IIS, которые мне не нужно выяснять, и перейду к завершению этого проекта.