Комментарии 79
Интересную конечно тему подняли. Теперь стоит думать, что и где применять
-21
>>есть вероятность нарваться на юзер-агента, который чтит спецификацию и выдаст предупрежление.
Пока про такой юзер-агент не слышал. Как появится — будем решать проблему :)
Пока про такой юзер-агент не слышал. Как появится — будем решать проблему :)
+18
Я тоже. Но есть вероятность, что они появятся, например, среди мобильных приложений. В любом случае, лучше быть в курсе=)
+1
А так же (к автору поста):
> Использовать 303, тогда старые клиенты не поймут, что от них хотят.
это какие, например?
> Использовать 303, тогда старые клиенты не поймут, что от них хотят.
это какие, например?
+2
Например:
Opera младше 4.0,
Internet Explorer младше 4.0
Может для кого-то критична поддержка и этих браузеров=)
Opera младше 4.0,
Internet Explorer младше 4.0
Может для кого-то критична поддержка и этих браузеров=)
+7
Например,
Zend_Http_Client
из ZF с включенной опцией strict_redirects
, которая, кстати говоря, по умолчанию выключена.+1
Мне кажется лишним выносить подобную логику в PHP (или любой другой серверный язык), выдачей «правильного» кода должен заниматься веб-сервер, когда увидит заголовок Location, если это действительно может на что-то повлиять (поскольку Apache отправляет 302, вероятно, это-таки ни на что не влияет :)). Так-то!
-5
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Не думаю что
return
будет корректным. В фреймворках обычно бросается некий Redirect_Exception
, который обрабатывается контроллером (корректно завершается работа). А если контроллера, как такового, нет то die()
или exit
именно то что нужно.0
НЛО прилетело и опубликовало эту надпись здесь
Яваскрипт мерзкий убрали бы…
0
Тогда уж было бы правильным ввести условие для header($_SERVER['SERVER_PROTOCOL']." 303 See Other").
Чтобы при $_SERVER['SERVER_PROTOCOL']=='HTTP/1.0' возвращался 302-й код.
Чтобы при $_SERVER['SERVER_PROTOCOL']=='HTTP/1.0' возвращался 302-й код.
+1
Неужели так сложно сделать защиту от повторного постинга без редиректа?
Всё же не для этого ИМХО редиректы придуманы.
Всё же не для этого ИМХО редиректы придуманы.
-5
да легко. например в форму внедряется скрытый ключ…
0
НЛО прилетело и опубликовало эту надпись здесь
Да, про 303 конечно соглашусь — ваша правда.
Хотя мне как-то ближе способ с дополнительным уникальным скрытым полем — он ко всему прочему от ботов защищает.
Хотя мне как-то ближе способ с дополнительным уникальным скрытым полем — он ко всему прочему от ботов защищает.
0
НЛО прилетело и опубликовало эту надпись здесь
ещё помогает задизэблить кнопку после нажатия
0
Да, вы совершенно правы — это ещё один аргумент чтобы отказаться от редиректа в пользу скрытого поля :)
0
НЛО прилетело и опубликовало эту надпись здесь
Ну, а откуда возьмется скрытое, сразу поле после того, как юзер сабмитил форму, если страница еще не успела загрузиться снова?
0
Скрытое поле генерится *до* сабмита формы и передаётся вместе с ней.
Если сервер видит что такое значение ему уже передавали — даёт отлуп.
Если сервер видит что такое значение ему уже передавали — даёт отлуп.
+1
Я имел ввиду вот этот момент:
>иногда пользователи успевают несколько раз отправить форму (кликая по кнопке в ожидании)
То есть если по вашему, то все равно нужно генерить яваскриптом либо новое значение для хайдена, либо дисэблить кнопку.
Однако, редирект — это более кошерно.
>иногда пользователи успевают несколько раз отправить форму (кликая по кнопке в ожидании)
То есть если по вашему, то все равно нужно генерить яваскриптом либо новое значение для хайдена, либо дисэблить кнопку.
Однако, редирект — это более кошерно.
0
оно там было с самого начала, с произвольным значением — если запросы приходят с одинаковыми значениями — нужно игнорировать все, кроме первого.
0
Отказываться от редиректа все-таки не надо.
С редиректом для пользователя сохраняется возможность свободно гулять по истории без предупреждений броузера «сейчас вы повторно отправите какие-то данные».
Т.е. использовать POST запросы только как setter'ы (что-то меняющие на стороне сервера, но ничего не отображающие), а GET — как getter'ы (только отображающие, но никогда не меняющие ничего на стороне сервера) — идеологически правильно.
Более того, если мы переходим по какому-то специальному урлу (линк с картинкой кнопки) и при этом что-то меняется в даных на стороне сервера, правильно и после этого сделать редирект.
С редиректом для пользователя сохраняется возможность свободно гулять по истории без предупреждений броузера «сейчас вы повторно отправите какие-то данные».
Т.е. использовать POST запросы только как setter'ы (что-то меняющие на стороне сервера, но ничего не отображающие), а GET — как getter'ы (только отображающие, но никогда не меняющие ничего на стороне сервера) — идеологически правильно.
Более того, если мы переходим по какому-то специальному урлу (линк с картинкой кнопки) и при этом что-то меняется в даных на стороне сервера, правильно и после этого сделать редирект.
+6
для бота не проблема запросить форму с уникальным скрытым полем перед отправкой. это скорее защита от CSRF.
+1
Отправлять форму ajax-запросом, если включен js.
0
Если автор поста проведет тестирование различных браузеров в такой ситуации, мы ему будем очень благодарны. Может быть все браузеры корректно себя ведут?
0
Не понял вопроса. Что значит «все браузеры корректно себя ведут»? Все браузеры, поддерживающие HTTP/1.1 понимают 303 статус. И все популярные браузеры интерпретируют 302 статус как 303.
0
Совершенно верно, все браузеры не являющиеся музейными экспонатами, ведут себя корректно. Я думаю, это вопрос скорее академического характера.
0
Есть какая практическая польза?
-1
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Врядли кто-то сейчас использует настолько старый клиент, который не поддерживает HTTP/1.0
Большинство сайтов хостятся на виртуальных хостингах, где без HOST заголовка не попадешь на нужный сайт.
Большинство сайтов хостятся на виртуальных хостингах, где без HOST заголовка не попадешь на нужный сайт.
+1
например, так: header('Location: /new/location', true, 303);
Например, не так. URL в Location должен быть абсолютным:
RFC 2616, п.14.30.
Например, не так. URL в Location должен быть абсолютным:
The field value consists of a single absolute URI.
Location = «Location» ":" absoluteURI
RFC 2616, п.14.30.
+2
И правда:) Несмотря на то, что все браузеры поддерживают относительные URL'ы, по стандарту он должен быть абсолютным.
+1
302 тоже все браузеры поддерживают.
уж если педантствовать — то во всем! ;)
кстати, если предположить, что некий сферический браузер в вакууме реализован строго по букве стандарта, то 302 не так страшно как относительный адрес.
уж если педантствовать — то во всем! ;)
кстати, если предположить, что некий сферический браузер в вакууме реализован строго по букве стандарта, то 302 не так страшно как относительный адрес.
0
есть еще одна проблема, на сей раз уже практическая.
ныне совершенно типична конфигурация сервера, когда фронтендом стоит nginx, проксирующий динамику на апач. Так вот проксирование делается по http/1.0; ответ http/1.1 будет просто некорректен (и может иметь крайне негативные последствия в виде отдачи chunked transfer encoding nginx-у, сделавшему запрос по 1.0 и этого никак не ожидающему); a http/1.0 303 формально некорректен, что будет практически — надо проверять.
ныне совершенно типична конфигурация сервера, когда фронтендом стоит nginx, проксирующий динамику на апач. Так вот проксирование делается по http/1.0; ответ http/1.1 будет просто некорректен (и может иметь крайне негативные последствия в виде отдачи chunked transfer encoding nginx-у, сделавшему запрос по 1.0 и этого никак не ожидающему); a http/1.0 303 формально некорректен, что будет практически — надо проверять.
-1
Хороший пример рака мозга, причем, заразного.
Итак, в вебе миллионы серверов с миллионами приложений, которые написаны с использованием 302. Старые клиенты, которые не знали про 303 постепенно отмирают, но приложения на серверах остаются и по-прежнему используют 302 вместо 303. И будут, потому что это вошло в образование веб-программистов и впитано с исходниками примеров из книжек.
Разработчики стандарта поступили не очень мудро. Нужно было быть ближе к народу и наделить 302 именно тем смыслом, который в него вкладывают те, кто его использует. А «старый 302» переименовать в 303-й =)
И все дела =)
Итак, в вебе миллионы серверов с миллионами приложений, которые написаны с использованием 302. Старые клиенты, которые не знали про 303 постепенно отмирают, но приложения на серверах остаются и по-прежнему используют 302 вместо 303. И будут, потому что это вошло в образование веб-программистов и впитано с исходниками примеров из книжек.
Разработчики стандарта поступили не очень мудро. Нужно было быть ближе к народу и наделить 302 именно тем смыслом, который в него вкладывают те, кто его использует. А «старый 302» переименовать в 303-й =)
И все дела =)
+5
Не надо париться по этому поводу :) Направление уже задано, и переделывать кучу софта смысла нет
-1
задумывался об этом, читая rfc. но пришел к выводу, что фактически это бесполезная хрень. все клиенты понимают 302 и автоматически редиректят, поэтому инсинуации в rfc про 303 ни кого не волнуют. :)
«проблему» стоило бы порешать лишь в одном случае — если бы браузеры действительно запрашивали потдветждение юзера при 302 редиректе. но этого нет и никогда не будет, потому, что так устроен современный интернет. :)
«проблему» стоило бы порешать лишь в одном случае — если бы браузеры действительно запрашивали потдветждение юзера при 302 редиректе. но этого нет и никогда не будет, потому, что так устроен современный интернет. :)
0
Неожиданно столкнулся с проблемой: IE9 делает 302 редирект после POST тоже с помощью POST, т.е., если я правильно понимаю, он отрабатывает 302 статус как 307, в то время, как Firefox и Chrome отрабатывают 302 статус, как 303.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Редирект после POST запроса