Для чего используется OPTIONS запрос (preflight)
Что проверяют
Понимаете ли вы, откуда в Network берётся лишний OPTIONS и почему запрос из браузера падает, а из Postman проходит. Следом обычно спрашивают, какой именно запрос вызывает preflight и как сделать так, чтобы его не было.
Как отвечать
Preflight это проверочный запрос, который браузер сам отправляет перед кросс-доменным запросом, если тот не считается «простым». Сервер отвечает, разрешает ли он такой запрос с этого origin, и только потом браузер отправляет настоящий.
Простой запрос: метод GET, HEAD или POST, заголовки только из безопасного списка, а Content-Type один из трёх: application/x-www-form-urlencoded, multipart/form-data, text/plain. Главное следствие: POST с Content-Type: application/json или любой запрос с Authorization уже требует preflight. То же касается PUT, PATCH и DELETE.
Что внутри обмена:
- запрос:
OPTIONSс заголовкамиOrigin,Access-Control-Request-MethodиAccess-Control-Request-Headers, без куки и без токена; - ответ: код 2xx,
Access-Control-Allow-Origin,Access-Control-Allow-Methods,Access-Control-Allow-Headers; - кэш:
Access-Control-Max-Ageизбавляет от проверки перед каждым запросом. Браузеры ограничивают значение сверху, Chromium держит не больше двух часов; - куки: при
credentials: 'include'нуженAccess-Control-Allow-Credentials: true, а*вAllow-Originуже не принимается.
Смысл preflight в защите серверов, которые про CORS не знают: форма на чужом сайте никогда не могла отправить им DELETE или JSON, и браузер сохраняет это ограничение.
Где спотыкаются
Считают, что CORS защищает сервер от атак. Это правило, которое исполняет браузер: curl и серверный код его не соблюдают, поэтому проверку прав он не заменяет.
Вешают проверку токена на все методы, и сервер отвечает на OPTIONS кодом 401. Preflight не несёт Authorization, такие запросы нужно пропускать до авторизации.
Лечат ошибку на фронтенде через mode: 'no-cors'. Запрос уйдёт, но ответ станет непрозрачным, и тело прочитать не получится. CORS настраивается только на сервере или прокси.