Нужно ли использовать HTTP-код перенаправления 302 или 307? - PullRequest
11 голосов
/ 18 марта 2010

Предположим, у меня есть страница на моем веб-сайте для отображения пресс-релизов за текущий месяц.
http://www.mysite.com/mediareleases.aspx

И по причинам, в которые стоит войти *, этой странице ДОЛЖНА быть предоставлена ​​строка запроса с текущим днем ​​месяца, чтобы создать этот список:
http://www.mysite.com/mediareleases.aspx?prevDays=18

Поэтому мне нужно перенаправить клиентов, запрашивающих http://www.mysite.com/mediareleases.aspx, на http://www.mysite.com/mediareleases.aspx?prevDays=whateverDayOfTheMonthItIs

.

У меня вопрос: если я хочу, чтобы Google проиндексировал страницу без параметра запроса, должен ли я использовать код состояния 302 или 307 для выполнения перенаправления?

Оба указывают, что страница «временно» переместилась - это то, чего я хочу, потому что страница «перемещается» каждый день, если вы понимаете мое значение.

[*] Я использую функцию .NET CMS с закрытым исходным кодом, поэтому мои руки связаны.

Ответы [ 4 ]

18 голосов
/ 18 марта 2010

Документация Google , похоже, указывает на то, что и 302, и 307 обрабатываются одинаково, и что "Googlebot будет продолжать сканировать и индексировать исходное местоположение".

Но перед лицом двусмысленности вы могли бы также покопаться в RFC и попытаться сделать правильную вещь с наивной надеждой, что сканеры сделают то же самое. В этом случае RFC 2616 § 10.3 содержит почти идентичные определения для каждого кода ответа, за одним исключением:

302: Поскольку перенаправление может * иногда изменяться , клиент ДОЛЖЕН продолжать использовать Request-URI для будущих запросов.

307: Поскольку перенаправление МОЖЕТ * время от времени изменяться, клиент ДОЛЖЕН продолжать использовать Request-URI для будущих запросов.

Что не поразило меня как существенное различие. Мое чтение таково, что 302 указывает клиентам, что веб-мастерам нельзя доверять, а 307 прямо говорит веб-мастерам, что клиенты им не будут доверять, поэтому они могут свободно изменять перенаправление.

Я думаю, что более выразительным моментом является примечание в определении 302:

Примечание. RFC 1945 и RFC 2068 указывают, что клиенту не разрешено изменять метод в перенаправленном запросе. Однако большинство существующих реализаций пользовательского агента обрабатывают 302 так, как если бы это был ответ 303, выполняя GET для значения поля Location независимо от исходного метода запроса. Коды состояния 303 и 307 были добавлены для серверов, которые хотят однозначно прояснить, какой тип реакции ожидается от клиента.

Что, на мой взгляд, указывает на то, что 302 и 307 в значительной степени эквивалентны, но клиенты HTTP / 1.0 не смогли правильно реализовать 302 в первый раз.

12 голосов
/ 29 декабря 2012

Краткий ответ: ни один. В большинстве случаев вы действительно хотите использовать код 303 .

Для длинного ответа, сначала нам нужен фон.

При получении кода перенаправления клиент может (A) загрузить новое местоположение, используя тот же тип запроса, или (B) он может перезаписать его и использовать GET.

Спецификация HTTP 1.0 не имела 303 и 307, она имела только 302, что предписывало поведение (A). Но на практике выяснилось, что (A) приводит к проблеме с отправленными формами.

Скажем, у вас есть контактная форма, посетитель заполняет ее и отправляет, а клиент получает 302 на страницу со словами «спасибо, мы свяжемся с вами». Форма была отправлена ​​с использованием POST, поэтому страница благодарности также загружается с использованием POST. Теперь предположим, что посетитель перезагружается; запрос повторно отправляется так же, как он был получен в первый раз, то есть с POST (и той же полезной нагрузкой в ​​теле). Конечный результат: форма отправляется дважды (и еще раз для каждой перезагрузки). Даже если клиент запрашивает у пользователя подтверждение перед тем, как сделать это, в большинстве случаев это все равно раздражает.

Эта проблема стала настолько распространенной, что производители клиентов решили переопределить спецификацию и выполнить запросы GET для перенаправленного местоположения. По сути, это был недосмотр в спецификации HTTP 1.0. Больше всего клиенты нуждались в 303 (и поведении (B) выше), но вместо этого они получали только 302 (и (A)).

Если бы HTTP 1.0 предлагал и 302, и 303, проблем бы не было. Но это не так, так что это привело к 302, который никто не использовал правильно. Так, HTTP 1.1 добавил 303 (крайне необходимо), но также решил добавить 307, что технически идентично 302, но является своего рода «явным 302»; он говорит: «Да, я знаю проблемы, связанные с 302, я знаю, что я делаю, дай мне поведение (А)».

Теперь вернемся к нашему вопросу. Теперь вы понимаете, почему в большинстве случаев вам нужно 303 .

Случаи, когда вы хотите сохранить тип запроса, очень редки. И если вы обнаружите, что у вас такой случай, ответ прост: используйте 302. Либо клиент говорит HTTP 1.0, и в этом случае он не может понять 307; или он говорит HTTP 1.1, что означает, что у него нет причин сохранять бунтарское поведение старых клиентов, т.е. он правильно реализует 302, так что используйте его!

4 голосов
/ 17 марта 2015

5 лет спустя ... обратите внимание, что поведение 307 было обновлено RFC-7231 # 6.4.7 в июне 2014 года и теперь значительно отличается от 302 в том смысле, что метод может не меняется:

Код состояния 307 (временное перенаправление) указывает, что цель ресурс временно находится под другим URI и пользовательским агентом НЕ ДОЛЖЕН изменять метод запроса, если он выполняет автоматический перенаправление на этот URI.

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

0 голосов
/ 18 марта 2010

Я чувствую твою боль. Что касается решения, сложно сказать, что будут делать поисковые системы. Кажется, у каждого свой способ обработки перенаправлений. Эта ссылка предполагает, что 302 будет индексировать содержимое перенаправленной страницы, но все равно будет использовать ссылку на главную страницу, но не ясно, что будет делать 307.

Еще один способ, с помощью которого вы можете продолжить, - это перенаправление JavaScript и тег <noscript>, объясняющий, что происходит. Это также запутает браузеры, не поддерживающие javascript, и вам следует действовать осторожно, чтобы избежать процедуры обнаружения хитрого сайта Google , но я подозреваю, что, пока ваш noscript содержит гиперссылку, соответствующую новой URL у тебя все будет в порядке.

В любом случае, я бы все равно продолжал выполнять чисто серверный запрос, если это вообще возможно. Черт возьми, если ваш ожидаемый трафик мал, вы можете рассматривать вашу домашнюю страницу как прокси в случае, когда нет строки запроса. Пусть он использует фоновый поток, чтобы запросить себя с помощью строки запроса и передать результаты. : -)

edit только что увидел, что вы используете .NET. Может быть, рассмотрим этот ответ от SO: C # Могу ли я изменить переменные Request.Form? .

...