Яка різниця між перенаправленням 302 та 307?


208

Яка різниця між a 302 FOUNDі a307 TEMPORARY REDIRECT HTTP-відповіддю?

Специфікація W3, схоже, вказує на те, що вони обидва використовуються для тимчасових переадресацій, і їх не можна кешувати, якщо відповідь спеціально цього не дозволяє.

Відповіді:


99

Різницеві стосується переадресації POST, PUTі DELETEзапитів , і які очікування сервера є для поведінки агента користувача ( RFC 2616):

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

Також прочитайте статтю Вікіпедії про коди переадресації 30x .


Отже, з точки зору аналізатора / агента / браузера, ми можемо просто трактувати 302 та 307 як однакові правильно? ( Точно той самий фрагмент коду можна використовувати для обробки обох справ без подальшого розрізнення?)
Pacerier

Ні - ви можете ставитися до 302 і 303 як до ідентичних, але 307 є різними.
Квентін Скусен

@kkhugs, Ні в якому разі не потрібно 1,0 браузера, щоб зробити get-302 так само, як get-307 робиться в 1.1 браузерах. Потрібен браузер 1.0, щоб робити пост-302 так само, як і діставати-302, за винятком того, що спочатку потрібно вимагати підтвердження користувача, щоб продовжити, і метод повинен бути після.
Pacerier

Потрібен браузер 1.1, щоб зробити get-302 так само, як і get-307.
Pacerier

161

307 сталося тому, що користувацькі агенти прийняли фактичну поведінку приймати POST-запити, які отримують відповідь 302 та надсилають GET-запит до заголовка відповіді Location.

Це неправильна поведінка - тільки 303 повинно спричинити, що POST перетворюється на GET. Користувацькі агенти повинні (але не) дотримуватися методу POST при запиті нової URL-адреси, якщо вихідний POST-запит повертав номер 302.

307 було введено, щоб сервери могли дати зрозуміти агенту користувача, що клієнт не повинен вносити змін методу під час виконання заголовка відповіді Location.


3
Будь-які приклади агентів користувача, які відповідають неправильно? Це зазвичай дуже невеликий відсоток відвідувачів?
goodguys_activate

6
@ makerofthings7 Усі броузери поводяться 302неправильно. Chrome 30, IE10. Це стало фактично некоректною реалізацією; це неможливо змінити, оскільки стільки веб-сайтів видають помилково 302. Насправді ASP.net MVC неправильно видає 302, залежно від того, що браузери керують ним неправильно.
Ян Бойд

1
@IanBoyd Тільки причини цього роблять через те, що 303він також був введений 307у специфікацію HTTP 1.1, і це дозволяє підтримувати зворотну сумісність з агентами користувача HTTP 1.0. Звичайно, справжнє питання полягає в тому, чи варто зараз взагалі обробляти агенти користувачів HTTP 1.0?
ewanm89

1
@ ewanm89 Здається, що рамки могли б створити правильно названий метод відповіді (наприклад Response.RedirectSeeOther), а якщо клієнту немає 1.1 (наприклад GET /foo.html, GET /foo.html HTTP/1.0), то видайте спадщину 302.
Ян Бойд

Це виглядає як 302 = 303 при переадресації.
vee

60

Хорошим прикладом 307 Internal Redirectдії є те, коли Google Chrome наштовхує HTTP-дзвінок на домен, який він знає, що вимагає суворої безпеки транспорту.

Браузер плавно переспрямовує, використовуючи той самий метод, що і вихідний дзвінок.

HTST 307 Внутрішній перенаправлення


2
Чи знаєте ви, коли Google реалізував цю функцію?
Тіме

2
Так, це я бачу, як це відбувається - наш сервер цього не надсилає - у хромованих розробниках це виглядає так, але це просто хром, який виконує переадресацію, оскільки у нас є заголовок суворої безпеки транспорту
Майк Нелсон

16

Блок-схема

  • 301: постійне переспрямування: URL-адреса стара та її слід замінити. Веб-переглядачі кешуватимуть це.
    Приклад використання: URL переміщено з /register-form.htmlдо signup-form.html.
    Метод зміниться на GET, відповідно до RFC 7231: "З історичних причин агент користувача МОЖЕ змінити метод запиту з POST на GET для наступного запиту."
  • 302: тимчасове переадресація. Використовувати лише для клієнтів HTTP / 1.0.Цей код статусу не повинен змінювати метод, але браузери все одно це робили. RFC зазначає: "Багато користувальницьких агентів перед HTTP / 1.1 не розуміють [303]. Коли взаємодія з такими клієнтами викликає занепокоєння, замість цього може використовуватися код статусу 302, оскільки більшість агентів користувача реагують на відповідь 302, як описано тут за 303. " Звичайно, деякі клієнти можуть реалізовувати це відповідно до специфікації, тож якщо взаємодія з такими стародавніми клієнтами не викликає побоювань, 303 краще для послідовних результатів.
  • 303: тимчасове переспрямування, зміна методу на GET.
    Приклад використання: якщо веб-переглядач надіслав POST /register.php, тепер завантажте (GET) /success.html.
  • 307: тимчасове переспрямування, повторення запиту однаково.
    Приклад використання: якщо веб-переглядач надіслав POST /register.php, це вказує йому повторити POST у /signup.php.
  • 308: постійне переспрямування, повторення запиту однаково. Якщо 307 - аналог "без зміни методу" 303, цей статус 308 є аналогом 301 "без зміни методу".

RFC 7231 (з 2014 року) дуже читабельний і не надто багатослівний. Якщо ви хочете знати точну відповідь, рекомендується прочитати. В деяких інших відповідях використовується RFC 2616 з 1999 року, але нічого не змінилося.

RFC 7238 визначає стан 308. Він вважається експериментальним, але його вже підтримали всі основні браузери у 2016 році.


302 не застаріло.
Джуліан Решке

У Вікіпедії @JulianReschke сказано, що "302 замінено на 303 і 307". Можливо, це тому, що я не є носієм мови, але для мене (у цьому контексті) витіснений і застарілий означає те саме: або використовувати 303, або 307, але не 302. Чи я читаю це неправильно?
Люк

Що не так, це припущення, що Вікіпедія має про це сказати. Якби 302 був застарілим, HTTP сказав би так.
Решке

@JulianReschke Ярмарок досить, я взяв до джерела та waddayaknow? Ви абсолютно праві. RFC насправді дуже зрозуміла, і дійсно вони навіть рекомендують 302 за певних умов. Жоден із "оновлених" та "застарілих" RFC, згаданих вгорі, не стосується кодів статусу, тому, мабуть, цей документ 1999 року справді є останнім у нас. Я оновлю свою відповідь.
Люк

Важливим є реєстр коду статусу IANA, і, таким чином, у цьому випадку RFC 7231.
Julian

8

ОЧАКУЄТЬСЯ для 302: переадресація використовує той самий метод запиту POST на NEW_URL

CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT POST NEW_URL

ACTUAL для 302, 303: метод запиту на переадресацію змін із POST на GET в NEW_URL

CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)
CLIENT POST OLD_URL -> SERVER 303 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)

ACTUAL для 307: переадресація використовує той самий метод запиту POST в NEW_URL

CLIENT POST OLD_URL -> SERVER 307 NEW_URL -> CLIENT POST NEW_URL

2

302 - тимчасова переадресація, яка генерується сервером, тоді як 307 - це внутрішня відповідь на переадресацію, що генерується браузером. Внутрішня переадресація означає, що переадресація здійснюється автоматично веб-переглядачем, в основному браузер змінює введений URL з http на https в запиті на отримання самостійно, перш ніж робити запит, тому запит про незахищене з'єднання ніколи не надсилається до Інтернету. Чи змінить браузер URL-адресу на https чи ні, залежить від списку попереднього завантаження hsts, який постачається з браузером. Ви також можете додати будь-який веб-сайт, який підтримує https, до списку, ввівши домен у список попереднього завантаження hsts вашого власного веб-переглядача, який знаходиться у chrome: //net-internals/#hsts.Що більше речей домени веб-сайтів можуть додати їх власники попередньо завантажити список, заповнивши форму на https://hstspreload.org/щоб він був попередньо встановлений у веб-переглядачах для кожного користувача, хоча я зазначив, що ви можете зробити це також для себе.


Поясню на прикладі:
я зробив запит на отримання доступу до http://www.pentesteracademy.com, який підтримує лише https, і я не маю цього домену у своєму списку попереднього завантаження hsts у своєму браузері, оскільки власник сайту не зареєстрував його поставляється з попередньо встановленим списком попереднього завантаження hsts. GET-запит на незахищену версію сайту переспрямовується на захищену версію (див. Http-заголовок, названий для цього у відповіді у наведеному вище зображенні). Тепер я додаю сайт до власного списку попереднього завантаження веб-переглядача, додаючи його домен у форму домену домену hsts на chrome: // net-Internals / # hsts, що змінює мій особистий список попереднього завантаження у моєму хромовому браузері. Обов’язково виберіть включити піддомени для Варіант STS є. Давайте подивимось запит і відповідь на той самий веб-сайт зараз після додавання його до списку попереднього завантаження hsts.заголовки запитів та відповідей



заголовки запитів та відповідей
ви можете побачити внутрішню переспрямування 307 там у заголовках відповідей, насправді ця відповідь генерується вашим браузером, а не сервером.
Також список попереднього завантаження HSTS може допомогти перешкодити користувачам дійти до незахищеної версії сайту, оскільки перенаправлення 302 схильне до mitm-атак.
Сподіваюся, я дещо допоміг вам зрозуміти більше про переадресації.


2

Спочатку було просто 302

| Response               | What browsers should do   |
|------------------------|---------------------------|
| 302 Found              | Redo request with new url |

Ідея полягає в тому, що:

  • якщо ви займалися в GETякомусь місці, ви переробили б його GETдо нової URL-адреси
  • якщо ви займалися в POSTякомусь місці, ви переробили б його POSTдо нової URL-адреси
  • якщо ви займалися в PUTякомусь місці, ви переробили б його PUTдо нової URL-адреси
  • якщо ви займалися в DELETEякомусь місці, ви переробили б його DELETEдо нової URL-адреси
  • тощо

На жаль, кожен браузер зробив це неправильно. Отримуючи a 302, вони завжди переходитимуть GETза новою URL-адресою, а не повторюють запит з тим же дієсловом ( наприклад , POST):

  • Мозаїка зробила це неправильно
  • Netscape скопіював помилки в мозаїку; тому вони неправильно зрозуміли
  • Internet Explorer скопіював помилки в Netscape; тому вони неправильно зрозуміли

Це стало фактично неправильним.

Усі браузери 302помилилися. Так 303і 307були створені.

| Відповідь | Що повинні робити браузери | Що браузери насправді роблять | | ------------------------ | ------------------------ --- | --------------------------- | | 302 Знайдено | Повторити запит з новою URL-адресою | GET з новою URL-адресою | | 303 Див. Інше | GET з новою URL-адресою | GET з новою URL-адресою | | 307 Тимчасовий перенаправлення | Повторити запит з новою URL-адресою | Повторити запит з новою URL-адресою |

У формі діаграми

5 різних видів переадресацій:

╔═══════════╤════════════════════════════════════════════════╗
║           │                Switch to GET?                  ║
║ Temporary │          No            │         Yes           ║
╠═══════════╪════════════════════════╪═══════════════════════╣
║ No        │ 308 Permanent Redirect │ 301 Moved Permanently ║
╟───────────┼────────────────────────┼───────────────────────╢
║ Yes       │ 307 Temporary Redirect │ 303 See Other         ║
║           │ 302 Found (intended)   │ 302 Found (actual)    ║
╚═══════════╧════════════════════════╧═══════════════════════╝

Як варіант:

| Response                 | Switch to get? | Temporary? |
|--------------------------|----------------|------------|
| 301 Moved Permanently    | No             | No         |
| 302 Found (intended)     | No             | Yes        |
| 302 Found (actual)       | Yes            | Yes        |
| 303 See Other            | Yes            | Yes        |
| 307 Temporary Redirect   | No             | Yes        |
| 308 Permanent Redirect   | No             | No         |

1

Також для адміністраторів сервера може бути важливо зазначити, що веб-переглядачі можуть подавати запит користувачеві, якщо ви використовуєте переадресацію 307.

Наприклад *, Firefox і Opera попросять у користувача дозволу на переадресацію, тоді як Chrome, IE і Safari будуть робити переадресацію прозоро.

* за бронезахисні SSL та TLS (стор. 192).


Це справедливо лише для небезпечних запитів, таких як POST.
Джуліан Решке

0

У деяких випадках використання зловмисник може зловживати 307 переадресаціями, щоб дізнатись, які саме дані є жертвами.

Додаткову інформацію можна знайти в розділі 3.1 з всеосяжного формального аналізу безпеки OAuth 2.0 .

Автори вищезазначеної роботи пропонують наступне:

Виправити. Всупереч нинішньому формулюванню стандарту OAuth, точний метод переадресації не є детальною інформацією про реалізацію, а є важливим для безпеки OAuth. У стандарті HTTP ( RFC 7231 ) визначено лише переадресація 303 однозначно, щоб викинути тіло запиту HTTP POST. Усі інші коди статусу переадресації HTTP, включаючи найбільш часто використовуваний 302, залишають у браузері можливість збереження POST-запиту та даних форми. На практиці браузери, як правило, переписують на GET-запит, тим самим видаляючи дані форми, за винятком 307 переадресацій. Тому стандарт OAuth повинен вимагати 303 переадресації для вищезазначених етапів, щоб вирішити цю проблему.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.