#php #pdf #google-chrome
#php #PDF #google-chrome
Вопрос:
У меня проблема с чтением PDF-файла в Chrome с помощью PHP.
Следующий код — это то, как я делаю в PHP
$path = "actually file path";
header("Pragma: public");
header("Expires: 0");
header("Content-type: $content_type");
header('Cache-Control: private', FALSE);
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Disposition: inline; filename="$filename"");
header('Content-Transfer-Encoding: binary');
header('Content-Length' . filesize($path));
ob_clean();
flush();
readfile($path);
Здесь я установил расположение содержимого на встроенное. Потому что я хочу отобразить PDF-файл, если в браузере пользователя есть встроенный плагин для просмотра pdf. Как вы, возможно, знаете, Chrome имеет встроенную программу просмотра PDF.
Проблема в том, что у меня на сервере куча PDF-файлов. Chrome может просматривать только некоторые из них. Я не могу понять, почему другие не могут работать таким же образом. Я проверил разрешение для каждого файла. Похоже, проблема не в разрешении.
Кто-нибудь знает, в чем проблема? Спасибо.
Комментарии:
1. Измените принудительную загрузку (расположение содержимого: вложение / Тип содержимого: приложение / октет-поток), загрузите / сохраните хороший PDF и плохой PDF и сравните то, что было сохранено, с тем, что есть на сервере.
2. @Marc Я пробую это. Оба они могут быть загружены и выглядеть одинаково. Я также сравниваю это с файлом на сервере. Они одинаковы. Когда я переключаюсь обратно на Content-disposition: встроенный. Это просто не работает. 🙁 Я даже сравниваю заголовок ответа. Они одинаковы.
3. Что произойдет, если вы попытаетесь просмотреть его напрямую, вместо того чтобы проходить через свой скрипт?
4. @Marc вы можете просмотреть это напрямую, не проходя через скрипт.
5. Тогда в чем смысл скрипта?
Ответ №1:
Я боролся с этой же проблемой. Это максимально близко к согласованным результатам во всех браузерах. Я думаю, что причина, по которой у вас могут возникнуть проблемы, заключается в том, что некоторые PDF-файлы слишком велики для корректной обработки readfile(). Попробуйте это:
$file = "path_to_file";
$fp = fopen($file, "r") ;
header("Cache-Control: maxage=1");
header("Pragma: public");
header("Content-type: application/pdf");
header("Content-Disposition: inline; filename=".$myFileName."");
header("Content-Description: PHP Generated Data");
header("Content-Transfer-Encoding: binary");
header('Content-Length:' . filesize($file));
ob_clean();
flush();
while (!feof($fp)) {
$buff = fread($fp, 1024);
print $buff;
}
exit;
Комментарии:
1. Это не работает ни в одном браузере или только в Chrome? Вы могли бы попробовать изменить размер буфера с 1024 на что-то меньшее. Если для параметра $ file задан полный путь к вашему документу, это должно сработать. Также обратите внимание на переменную $myFileName в одном из заголовков. Это необходимо установить или удалить.
2. Кажется, я получаю экран бесконечной загрузки.
3. Хороший вызов ob_clean () и flush ()
4. Это решение хорошо сработало для меня, хотя я получаю содержимое для PDF-файла из базы данных, я использовал file_get_contents () для получения содержимого из PDF-файла при вводе его в БД.
5. У меня здесь проблема. Заголовок моего PDF-файла не такой, как я установил в заголовке заголовка («Content-Disposition: inline; filename =».$ myFileName.»»); Есть какие-нибудь подсказки, как это можно сделать?
Ответ №2:
У меня была похожая проблема, но я заметил, что порядок имеет значение. Кажется, что ; filename=
вокруг него должны быть кавычки, Content-Disposition: attachment
попробуйте это:
$file = "/files/test.pdf";
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
$mime = finfo_file($finfo, $file);
header('Pragma: public');
header('Expires: 0');
header('Content-Type: $mime');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="'.basename($file).'"'));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Length' . filesize($file));
ob_clean();
flush();
readfile($file);
Комментарии:
1. Да, загрузка открывается из finder, но на панели загрузки Chrome не отображается сообщение «Не удалось загрузить PDF-документ» (если не использовать «системный просмотрщик»). После десятков примеров, включая решения на этой странице … это тот, который остановил CHROME «Ошибка не удалось загрузить PDF-документ. Всплывающее окно «Перезагрузить». вот с чего я изначально начал:
header('HTTP/1.1 200 OK'); header('Content-type:application/pdf'); header('Content-Disposition:attachment; filename="'.basename($f).'"');
и отлично работал в Firefox.
Ответ №3:
я исправил этот способ
$path = 'path to PDF file';
header("Content-Length: " . filesize ( $path ) );
header("Content-type: application/pdf");
header("Content-disposition: inline; filename=".basename($path));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
ob_clean();
flush();
readfile($path);
Ответ №4:
Была та же проблема, chrome не отображал встроенный PDF-файл, зависал при загрузке. Решением было добавить header('Accept-Ranges: bytes')
.
Мой полный код:
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="'.$title.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($file));
header('Accept-Ranges: bytes');
header('Expires: 0');
header('Cache-Control: public, must-revalidate, max-age=0');
Ответ №5:
Для меня добавление следующего заголовка исправило эту досадную ошибку Chrome (?):
header('HTTP/1.1 200 OK');
Ответ №6:
После нескольких часов, потраченных впустую … я добавил комментарии, чтобы указать, что у @Kal есть единственное решение, которое сработало. Но почему-то этого недостаточно…это такая невозможная и расстраивающая проблема, когда Chrome делает это:
Ошибка при загрузке PDF-документа. Перезагрузите
Вот разница, которая положила конец пытке.
- // Waste time with chrome:
- header("Content-type:application/pdf");
- header("Content-Disposition:attachment;filename=$file_basename");
- readfile($file);
exit();
---------------------------
// Deliver the file:
header('Pragma: public');
header('Expires: 0');
header('Content-Type: $mime');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Length'.filesize($file));
ob_clean();
flush();
readfile($file);
exit();
Около тридцати минут я дурачился с различными вариантами этого … но я не мог указать «Добавить HTTP 200«, а не «добавить байты«, не «заключить ваше имя файла в кавычки«, не «отделить окончание файла«. Ни одно из них не сработало.
(Еще раз спасибо @Kal).
Ответ №7:
У меня была эта проблема, я боролся почти 6 часов и, наконец, заставил ее работать. Мое решение похоже на приведенные выше ответы, но приведенные выше ответы не завершены. Для решения этой проблемы есть три шага.
Шаг 1. Перейдите в файл php.ini и добавьте эту строку.
output_buffering = False
Шаг 2.
Эта ошибка возникает, если вы открываете большой PDF-файл. Итак, чтобы решить эту проблему, непосредственно перед добавлением заголовков убедитесь, что вы вставили эти две строки.
set_time_limit(0);
ini_set('memory_limit', '100M'); //the memory limit can be more or less depending on your file
Шаг 3.
Добавьте приведенные ниже заголовки и код для чтения файла, чтобы окончательный код выглядел следующим образом.
set_time_limit(0);
ini_set('memory_limit', '100M');
$file = "path/to/file.pdf";
header('Content-Type: application/pdf');
header('Content-Disposition: inline;
filename="yourfilename.pdf"'); //not the path but just the name
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($file));
header('Accept-Ranges: bytes');
header('Expires: 0');
header('Cache-Control: public, must-revalidate, max-age=0');
ob_clean();
flush();
readfile($file);
exit();
100% рабочее решение. Если у вас возникнут какие-либо проблемы, дайте мне знать 🙂