Comments 39
Ошибка на ошибке.
+3
Не правильней ли будет исправить ошибки в приложениях?
+5
Правильно.
+1
Правильней, это несомненно!
Однако за много лет их так никто и не исправил.
Более того: в официальной документации по языку PHP употребление функции header() объясняют на примере«header("HTTP/1.0 404 Not Found")», а не «header($_SERVER['SERVER_PROTOCOL']. " 404 Not Found")», поэтому можно с превеликой уверенностию и в будущем ожидать приумножения в числе именно таких приложений.
Стало быть, популяризация быстрого обходного пути, во всяком случае, небесполезна. (Особенно для тех несчастных, на кого давит заказчик или начальство, требуя наладить сайтвот прям щазз; хорошо, что мне не довелось попасть в их число по этому поводу.)
Объяснение же глубинной причины ошибки поспособствует её надлежащему исправлению со временем.
Однако за много лет их так никто и не исправил.
Более того: в официальной документации по языку PHP употребление функции header() объясняют на примере
Стало быть, популяризация быстрого обходного пути, во всяком случае, небесполезна. (Особенно для тех несчастных, на кого давит заказчик или начальство, требуя наладить сайт
Объяснение же глубинной причины ошибки поспособствует её надлежащему исправлению со временем.
+20
Разработчикам web-приложений на будущее: у функции
header()
есть третий параметр $http_response_code
. Я, например, пользуюсь им таким образом: header('Content-Type:', true, $response->getStatusCode());
, тем самым еще и сбрасывая значение заголовка Content-Type, которое устанавливает Apache (например, если это публичный хостинг, и у меня нет прав на редактирование httpd.conf/.htaccess).+5
Сразу уточню, что значение-то указанного заголовка сбрасывается оттого, что второй параметр равен true, причём по умолчанию он и так равен true (его бы и указывать не пришлось, кабы не необходимость указать третий параметр после него).
+2
Ну, и статус-код тогда не от балды брать, а согласно RFC. Но не факт, что все браузеры поймут.
0
const OK = 200;
const CREATED = 201;
const NO_CONTENT = 204;
const RESET_CONTENT = 205;
const PARTIAL_CONTENT = 206;
const MOVED_PERMANENTLY = 301;
const FOUND = 302;
const SEE_OTHER = 303;
const NOT_MODIFIED = 304;
const BAD_REQUEST = 400;
const UNAUTHORIZED = 401;
const FORBIDDEN = 403;
const NOT_FOUND = 404;
const RANGE_NOT_SATISFIABLE = 416;
const INTERNAL = 500;
const UNAVAILABLE = 503;
Я надеюсь, что хотя бы эти коды все браузеры понимают (ну, те, что не поймут, уже пойдут для REST-приложений со своим desktop-клиентом)?
0
P.S. Я про конкретно статус-коды (числа), а не про сообщения вроде «Not Found», которые, ЕМНИП, не являются строго задекларированными, и клиент их вовсе не обязан парсить.
0
Проверял (правда давно): 201 с Locatioon не работал (вместо него приходится использовать 303), с 301 и 302 вообще ничего не ясно никому, настолько, что ввели 303 и 307, чтобы не путаться больше, с 503 с Retry-After тоже какие-то проблемы были.
+1
Есессено, что потом он задается нужным (вместе с другими заголовками). Просто если контент какой-то левый и неизвестный (мало ли), то посылать
Content-Type: text/html
как-то неправильно, ИМХО. Тогда уж какой-нить text/plain или application/octet-stream…0
Потому что это пример работы процедуры header, и ни к чему его приукрашивать переменной $_SERVER, которая собственно к самой процедуре никак не относится.
Что касается статьи, то на каждого мудреца довольно простоты :) Я например, с таким никогда не сталкивался (потому что не использую друпалы, джумлы и т.д.), но думаю, что многие будут благодарны вам за этот фикс.
Что касается статьи, то на каждого мудреца довольно простоты :) Я например, с таким никогда не сталкивался (потому что не использую друпалы, джумлы и т.д.), но думаю, что многие будут благодарны вам за этот фикс.
+2
> nginx полагается на протокол HTTP версии 1.0 при общении с бэкэндом.
А почему так? Если в заголовке явно указано 1.1?
Новой эту версию не назовешь, ибо лет 10 как приняли 1.1.
А почему так? Если в заголовке явно указано 1.1?
Новой эту версию не назовешь, ибо лет 10 как приняли 1.1.
-1
Потому что при общении с бекендами возможности http 1.1 не востребованы. А ответ версии 1.1 на запрос версии 1.0 — это явная ошибка. Кстати, начиная с какой-то версии nginx всетаки поддерживает общение с бекндами на http 1.1.
+3
То, что возможности невостребованы — ещё не повод не поддерживать самый популярный протокол вообще. Явно косяк nginx-а, тем более там нет каких-то драматических отличий.
-5
Это не косяк nginx. Он-то как раз никакх соглашений не нарушает. А то, что он обращается к серверу по 1.0 — вполне логично (зачем лишние манипуляции при выполнении запроса?).
+2
Затем, что это ничем, кроме абстрактных перфекционистских рассуждений об идеальном мире, не обоснованное ограничение, жестко накладываемое nginx-ом на бэкенд. Который может быть вообще любым и допустим http 1.0 не держать вообще как класс. Что в данном случае и вылезло.
-4
Нахрена вообще люди протоколы выдумывают, если по вашей логике в ответ все равно может прийти все что угодно?
+4
Стандарт это вещь в себе. Особенно у буржуев, где они являются рекомендацией (в отличие от гостов, имеющих силу закона).
Есть золотое правило: строго придерживаться стандартов при записи и допускать любые имеющие смысл отклонения при чтении. В случае nginx-a оно не выполнено.
Есть золотое правило: строго придерживаться стандартов при записи и допускать любые имеющие смысл отклонения при чтении. В случае nginx-a оно не выполнено.
-3
Стандарты для того и придуманы чтобы их соблюдать.
Если Apache не следует стандартам при этом заявляя что им соответствует, то нужно его исправлять.
Если предугадывать все возможные криворукости других программистов, то никаких человекочасов не хватит.
Это не касается взаимодействия с потенциально неграмотным пользователем, с которым вы вероятно перепутали данную ситуацию.
Если Apache не следует стандартам при этом заявляя что им соответствует, то нужно его исправлять.
Если предугадывать все возможные криворукости других программистов, то никаких человекочасов не хватит.
Это не касается взаимодействия с потенциально неграмотным пользователем, с которым вы вероятно перепутали данную ситуацию.
+5
не обоснованное ограничение, жестко накладываемое nginx-ом на бэкендНу да, прямо, очень жёсткое ограничение — расчёт на соблюдение стандарта)
может быть вообще любым и допустим http 1.0 не держать вообще как классПоддерживает 1.1 и отказывается поддерживать 1.0? Имхо, это экзотический случай, в отличии от поддержки 1.0 и неподдержки 1.1, который редок, конечно, тоже, но по крайней мере логичен.
+3
> Который может быть вообще любым и допустим http 1.0 не держать вообще как класс.
Насколько я понимаю, любой сервер, корректно поддерживающий только http 1.1 — автоматически корректно поддерживает http 1.0 (за вычетом неверной версии протокола в заголовке). Проблема вылезла от того, что apache некорректно поддерживает http 1.1.
Насколько я понимаю, любой сервер, корректно поддерживающий только http 1.1 — автоматически корректно поддерживает http 1.0 (за вычетом неверной версии протокола в заголовке). Проблема вылезла от того, что apache некорректно поддерживает http 1.1.
+5
> Явно косяк nginx-а.
Апачь отдает ответ чанками клиенту (nginx), который не только не указал в запросе, что он может принимать чанки, но и использовал версию протокола, в которой вообще ничего такого нет. Это не говоря уже о том, что чанки в принципе нужны только при keep-alive соединениях, а nginx явно посылает бекенду Connection: close. И все равно косяк nginx. Ах он сукин сын :)
Апачь отдает ответ чанками клиенту (nginx), который не только не указал в запросе, что он может принимать чанки, но и использовал версию протокола, в которой вообще ничего такого нет. Это не говоря уже о том, что чанки в принципе нужны только при keep-alive соединениях, а nginx явно посылает бекенду Connection: close. И все равно косяк nginx. Ах он сукин сын :)
+25
Апач в данном случае не при чем — его просто так настроили.
Косяк nginx-а в неподдержке http 1.1, которому уже сто лет в обед.
Косяк nginx-а в неподдержке http 1.1, которому уже сто лет в обед.
-9
Насчет Drupal Вы не правы — только древняя 5-я версия так делает. Распространенная 6-я уже не содержит ошибки:
drupal_set_header($_SERVER['SERVER_PROTOCOL']. ' 404 Not Found');
(http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_not_found/6)
drupal_set_header($_SERVER['SERVER_PROTOCOL']. ' 404 Not Found');
(http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_not_found/6)
+3
Лучи счастья автору!!! Сколько времени я на это угробил и сколько еще мне его автор сэкономил!
+7
Проблема однозначно на стороне бэк-энда.
В качестве обхода проблемы (особенно если используется не Apache) по идее также должна помочь установка nginx >= 1.1.4 или chunked_transfer_encoding off.
В качестве обхода проблемы (особенно если используется не Apache) по идее также должна помочь установка nginx >= 1.1.4 или chunked_transfer_encoding off.
0
Sign up to leave a comment.
Четыре зловещие шестнадцатеричные цифры на страницах ошибок — и как преодолеть их