Кнопка загрузки Chrome загружает файл PHP вместо PDF

#php #google-chrome #pdf #reporting-services

Вопрос:

В Интернете есть много похожих вопросов, ни один из них не соответствует одному и тому же сценарию и не дает никакого представления о том, что происходит или как это решить. Я надеюсь, что смогу предоставить дополнительную информацию при тестировании и сузить круг вопросов, которые, по моему мнению, происходят и вызывают эту проблему.

Я повторяю и просматриваю PDF-файл, созданный с помощью SSRS, на экране, и большую часть времени я вижу правильные заголовки, которые явно задаю, но у меня есть один тип отчета, который, похоже, изменяет заголовок управления содержимым. Когда это произойдет, кнопка загрузки в Chrome предложит загрузить мой controller.php файл вместо PDF.

Я использую PHP, работающий на сервере IIS. Вот заголовки, которые я явно задаю в своем коде:

    header('content-type:application/pdf');
   header('Cache-Control: store; cache; no-revalidate');
   header('Content-Disposition: inline; filename=' . $this->sFileName . '.pdf');
 

Для большинства отчетов, которые я вывожу, заголовки в них соответствуют этим значениям. Вот пример отчета о котировках, который выводит его правильно:

Отчет о котировках

Вот результат при нажатии кнопки «Загрузить» в окне предварительного просмотра PDF Chrome:

Цитата Скачать

В моем тестировании нескольких отчетов есть один, в частности, Отчет о заказе, который, похоже, всегда изменяет заголовок расположения содержимого:

Отчет о заказе

Вот результат при нажатии кнопки «Загрузить» в окне предварительного просмотра PDF Chrome:

Controller.php Скачать

Я провел тест, в котором я прокомментировал строку заголовка Cache-Control, которую я устанавливаю выше, и повторно запустил отчет о котировках. Я получил те же результаты для заголовка управления кэшированием, которые я получаю для отчета о заказе, и получил те же результаты, когда он загружает мой controller.php файл вместо PDF. Вот почему я считаю, что это как-то связано с тем заголовком, который является причиной этого. Там, где еще я явно устанавливаю этот заголовок в своем коде, что-то должно его изменить. Я надеюсь, что кто-то знает что-то об этом заголовке конкретно в PHP, что может привести к изменению значения.

Заранее спасибо!

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

1. Похоже, запрос попадает в ASP.net служба, которая запущена и вместо этого загружает контроллер. Вам следует отключить IIS, если он не используется… что бы ни происходило с прокси-сервером, IIS имеет приоритет. (мое общее предположение). Это говорит о X-Powered-By том, что обе конечные точки подключены к разным службам. Отсутствие конфигурации на сервере, похоже, является вашей проблемой, если бы мне пришлось сделать обоснованное предположение об этом.

2. Спасибо за предложение. Я убрал ASP.NET Заголовок HTTP — ответа в IIS. Он больше не отображается в заголовке x-powered-by (теперь только PHP/7.3.3), но управление кэшем все еще изменяется и по-прежнему возникает та же проблема.

3. Удаление заголовка не означает, что запрос не попадет в службу, как вы перенаправляете запрос? Nginx/Apache2? Это вероятная проблема.

4. Извините, конфигурации серверов не являются моей областью знаний. Это мой сайт разработки, размещенный локально через IIS. Насколько мне известно, у меня нет настроенного прокси-сервера.

5. Я предполагаю, что IIS-это ваша проблема. Это проксирование вашего PHP-приложения, а не пересылка запросов. Поэтому, если он видит запрос, который он может обработать, он обрабатывает его, а не передает запрос. Лучше всего использовать Apache2 или Nginx локально вместо другого веб-приложения.

Ответ №1:

Я смог решить эту проблему в своем сценарии.

В итоге я понял, что каждый раз, когда я печатал отчет о заказе, мои заголовки не отправлялись. Проверка статуса headers_sent() на последних строках возвращалась false .

Теперь, почему он не отправлял заголовки только для этого одного типа отчета, я понятия не имею… После того, как я снова и снова тщательно просматривал строки кода, все казалось идентичным с того момента, когда я печатал отчет о котировках. Тем не менее отчет с цитатами последовательно отправлял заголовки , как и ожидалось $file , и передавал $line параметры, чтобы headers_sent() вывести правильный файл и строку#, которые я повторял в PDF, возвращаясь из служб SSRS. Я заметил это, потому что отчет о заказе попал в мой session_start() код, где его не должно было быть, если выводятся заголовки. Это очень странно, потому что отчет о заказе все еще выводился на экран, поэтому я действительно понятия не имею, почему он думает, что заголовки не отправлялись.

В итоге я просто добавил ob_flush() право после повторения отчета, чтобы убедиться, что содержимое и заголовки будут отправлены. Похоже, это работает последовательно.

Если у кого-нибудь есть какое-либо представление о том, почему не были отправлены заголовки. Мне было бы интересно услышать в комментариях.