После POST, я должен сделать 302 или 303 перенаправления?

Распространенным сценарием для веб-приложения является перенаправление после POST, который изменяет базу данных. Как перенаправление на вновь созданный объект базы данных после того, как пользователь его создал.

Похоже, что большинство веб-приложений используют перенаправления 302, но 303, кажется, является правильной вещью в соответствии со спецификацией, если вы хотите, чтобы URL, указанный в перенаправлении, был получен с помощью GET. Технически, с 302, браузер должен извлекать указанный URL-адрес тем же методом, что и исходный URL-адрес, которым будет POST. Большинство браузеров этого не делают.

302 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

303 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Так я должен использовать 302 или 303?

5 ответов

Решение

Зависит.
303 и 307 ответов были добавлены в HTTP1.1.
Таким образом, клиентские агенты, строго соответствующие HTTP1.1 RFC, должны подойти с ответом 303.
Но могут быть агенты, которые не являются полностью совместимыми или HTTP1.0-совместимыми и не смогут обрабатывать 303.
Поэтому, чтобы быть уверенным в том, что ответ вашего приложения может быть корректно обработан большинством клиентских реализаций, я думаю, что 302 - самый безопасный вариант.
Выдержка из RFC-2616:

Примечание. Многие пользовательские агенты до HTTP/1.1 не понимают статус 303. Когда взаимодействие с такими клиентами является проблемой, вместо этого может использоваться код состояния 302, поскольку большинство пользовательских агентов реагируют на ответ 302, как описано здесь для 303.

Правильный - 303.

Я использую его и не обнаружил никаких проблем с совместимостью с UA, более новыми, чем Netscape 4 (1998, выпущенный 17 лет назад).

Если вы используете 302, вы рискуете, что UA повторно отправит POST на новый URL вместо того, чтобы переключиться на GET.

Тем не менее, если вы беспокоитесь о клиентах HTTP/1.0 (которые не поддерживают vhosts и, вероятно, не смогут получить доступ к вашей странице в любом случае), то вам следует включить HTML со ссылкой на новую страницу в текст ответа 303 (веб-серверы, такие как Apache, уже делают это).

В большинстве серверных языков механизм перенаправления по умолчанию использует 302:

  • Джава response.sendRedirect(..) использует 302
  • ASP.NET response.Redirect(..) использует 302
  • PHP header("Location: ..") использует 302
  • RoR redirect_to использует 302
  • так далее..

Поэтому я бы предпочел это, а не устанавливать статус и заголовки вручную.

Теоретически, вы (и весь мир) должны использовать 303, как вы отметили. Но также большинство браузеров реагируют на 302 так, как они должны реагировать на 303. Так что, в целом, кажется, что не имеет значения, отправляете ли вы 302 или 303. В ссылке, которую вы предоставили для спецификации 303, есть интересное примечание:

Примечание. Многие пользовательские агенты до HTTP/1.1 не понимают статус 303. Когда взаимодействие с такими клиентами является проблемой, вместо этого может использоваться код состояния 302, поскольку большинство пользовательских агентов реагируют на ответ 302, как описано здесь для 303.

Важно отметить пользовательские агенты до-HTPTP / 1.1, так что, может быть, это было важно некоторое время назад, но я не верю, что это так.

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

При предоставлении местоположения нового ресурса, созданного запросом POST, 201 ("Создано") является подходящим ответом.

HTTP / 1.1: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Протокол публикации Atom: http://tools.ietf.org/html/rfc5023

Это означает, что веб-браузер, вероятно, не будет перенаправлять на новый URL; пользователь должен перейти по ссылке, чтобы перейти к новому элементу (эта ссылка может быть указана в теле ответа, а также в заголовке "Местоположение").

Другие вопросы по тегам