Ответ вслух Middle CORS обновлено

Как отладить ошибку CORS

Вопрос

В проде у фронта посыпались ошибки CORS после переезда API на новый домен. Как бы ты искал причину?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Первым делом смотрю в DevTools, какой запрос упал. Если это OPTIONS, проблема в preflight: сервер или прокси перед ним отвечают 404, 401 или редиректом, а браузеру нужен 2xx с разрешающими заголовками.

Что должно прозвучать в ответе

  • Открыть вкладку Network и найти, на каком запросе падает: preflight OPTIONS или основной

  • Проверить `Origin` запроса и `Access-Control-Allow-Origin` ответа: совпадает ли точно (схема, порт, www)

  • Если падает preflight: отвечает ли сервер 2xx на OPTIONS, не режет ли его авторизация или прокси

  • Сверить `Allow-Methods` и `Allow-Headers` с тем, что реально шлёт фронт

  • При куках проверить `Allow-Credentials`, отсутствие `*` и `SameSite=None; Secure` у куки

  • Проверить кеширование: `Vary: Origin` на CDN и nginx, не отдаёт ли CDN чужой заголовок

Что могут спросить следом

  • Почему ошибка видна только в браузере, а curl работает?
  • Что будет, если nginx отдаёт CORS-заголовки, а приложение тоже?
  • Зачем нужен Vary: Origin?

Разбор

Первым делом смотрю в DevTools, какой запрос упал. Если это OPTIONS, проблема в preflight: сервер или прокси перед ним отвечают 404, 401 или редиректом, а браузеру нужен 2xx с разрешающими заголовками. Если упал основной запрос, сравниваю Origin и Access-Control-Allow-Origin побайтно: частая история, когда в белом списке https://app.ru, а фронт открыт на https://www.app.ru. Дальше сверяю методы и заголовки: фронт мог начать слать новый заголовок, которого нет в Allow-Headers. Если используются куки, проверяю, что сервер не отдаёт звёздочку, стоит Allow-Credentials: true, а кука на новом домене выставлена с SameSite=None; Secure. Ещё одна ловушка это дублирование: и nginx, и приложение добавляют Access-Control-Allow-Origin, и браузер отвергает ответ с двумя значениями. И наконец кеш: если CDN закешировал ответ с одним origin без Vary: Origin, другим сайтам он придёт с чужим разрешением.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме