Что такое Preflight запрос

Ответ

Preflight — это CORS-запрос типа OPTIONS, который браузер автоматически отправляет перед основным запросом, если он соответствует определённым критериям сложности.

Когда происходит:

  • Нестандартные HTTP-методы (не GET/POST/HEAD)
  • Нестандартные заголовки (кроме безопасных, например, Content-Type с application/json)
  • Запросы с учётными данными (withCredentials)

Пример:

fetch('https://api.example.com/data', {
  method: 'PUT',
  headers: { 'X-Custom-Header': 'value' }
});

Браузер сначала отправит OPTIONS-запрос с заголовками Access-Control-Request-Method: PUT и Access-Control-Request-Headers: X-Custom-Header. Сервер должен ответить с разрешающими CORS-заголовками (Access-Control-Allow-*), и только тогда выполнится основной запрос.

Важно: Preflight не происходит для простых запросов (GET/POST с стандартными заголовками и Content-Type: application/x-www-form-urlencoded).

Ответ 18+ 🔞

А, ну это же та самая хуйня, когда браузер начинает умничать! Смотри, есть такая штука — Preflight. Это когда твой браузер, этот зануда, перед тем как отправить нормальный запрос, вдруг решает: «А не спросить ли у сервера разрешения?» И шлёт ему запрос типа OPTIONS, как будто стучится в дверь: «Можно, я, блядь, зайду?»

Когда эта паранойя срабатывает:

  • Если ты используешь какие-то нестандартные методы, не эти скучные GET или POST. Захотел PUT или DELETE — всё, жди проверки.
  • Сунул в запрос свои, особенные заголовки, кроме базовых. Типа X-I-Am-Cool: true. Браузер такой: «О, самодеятельность! Надо согласовать!»
  • Или если запрос с куками/учётными данными летит (withCredentials). Тут уж без разговоров — предъяви пропуск!

Сценка из жизни, чтобы понятнее было:

Представь, ты пишешь такой код, епта:

fetch('https://api.example.com/data', {
  method: 'PUT',
  headers: { 'X-Custom-Header': 'value' }
});

И что делает твой браузер? Он сначала, блядь, высылает вперёд «разведчика» — OPTIONS запрос. И кричит серверу: «Слушай, я тут хочу PUT применить и заголовок X-Custom-Header притащить! Ты не против?» В заголовках это выглядит так: Access-Control-Request-Method: PUT и Access-Control-Request-Headers: X-Custom-Header.

Сервер, если он не конченый мудак, должен ответить: «Да ради бога, хуле!» — и выдать разрешительные заголовки (Access-Control-Allow-*). И только после этого, довольный браузер отправит твой настоящий, основной PUT-запрос.

Но есть нюанс, ёпта! Не за всё браузер так занудничает. Есть так называемые «простые запросы». Если это обычный GET или POST со стандартными заголовками и Content-Type: application/x-www-form-urlencoded, то браузер не парится и шлёт сразу. А вот если начал выёбываться с application/json — всё, приехали, жди preflight. Вот такая, блядь, магия!