CORS: просто и понятно говорим про ошибки кроссдоменных запросов

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

Всем привет!

Меня зовут Радик, я frontend developer компании Creative. И сегодня я хочу поднять тему, которая касается и фронта и бэка, и окружает нас с вами каждый день. Речь пойдёт об ошибках CORS и как их можно обойти.

Уверен, что многим разрабам знакома ситуация, когда ты работаешь над приложением, оно запущено локально, и тебе нужно сделать из него запросы к различным удалённым ресурсам. В этот момент «что-то идёт не так», и ты видишь на своём экране миллион ошибок в консоли браузера. Почему они появляются? Давайте разбираться вместе. В этой статье расскажу о средствах защиты браузера и о том, что он может от вас скрывать в процессе кроссдоменных запросов. Фича: об ошибках будем говорить в картинках :)

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

SOP – Same Origin Policy

Рассмотрим кейс. Мы заходим на какой-то незнакомый сайт, созданный потенциальным злоумышленником. Внешне пока не видим ничего подозрительного, но пока мы находимся на этом сайте, злобный скрипт уже готовит запрос к серверу банка, в котором мы залогинены, и пытается получить наши данные:

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

Как же браузер пытается нас от этого защитить? Он использует Политику одинакового источника: Same Origin Policy (SOP).

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

В тех случаях, когда запрос отправляется на ресурс, у которого отличается домен / порт / протокол, – браузер по умолчанию понимает, что он кроссдоменный и применяет политику безопасности:

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

CORS – Cross Origin Resource Sharing

Что же делать в том случае, когда нам необходимо разрешить для браузера взаимодействие между различными ресурсами?

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

Браузер должен отправить в запросе заголовок:

**origin: htttps://good-website.com**

Сервер проверит, откуда к нему пришёл запрос, и (если этот домен разрешён) в ответе вернёт заголовок:

**access-control-allow-origin: htttps://good-website.com**

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

ACAH – Access-Control-Allow-Headers

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

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

Так получается, потому что по умолчанию при кроссдоменных запросах браузер разрешает чтение только следующих заголовков ответа:

  • Cache-Control

  • Content-Language
  • Content-Length
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

Поэтому в network вкладке браузера мы видим абсолютно все интересующие нас заголовки, а из кода JS они будут нам недоступны.

CORS: просто и понятно говорим про ошибки кроссдоменных запросов
CORS: просто и понятно говорим про ошибки кроссдоменных запросов

Для того чтобы браузер разрешил доступ к этим заголовкам, в ответе должен быть указан заголовок Access-Control-Allow-Headers.

В нём нужно перечислить заголовки, доступ к которым разрешён браузером:

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

Специальное значение * позволяет разрешить для использования любые заголовки, но только в том случае, если в изначальном запросе нет cookie или данных аутентификации. В противном случае оно будет рассматриваться как буквальное имя заголовка «*».

Proxy как одно из возможных решений проблемы при локальной разработке

Рассмотрим ещё один кейс. Нам нужно сделать кроссдоменный запрос из приложения, которое развёрнуто локально. Но такой запрос в нужный нам момент не обрабатывается должным образом на сервере. Картинка для понимания.

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

Как быть? Можно запустить локальный proxy сервер, который будет пересылать данные между нашим приложением и сервером, добавляя необходимые заголовки:

CORS: просто и понятно говорим про ошибки кроссдоменных запросов

Можно сделать простой proxy сервер на Node.js для решения проблемы с кроссдоменными запросами:

  • Для этого переходим в директорию, в которой вы хотите создать прокси сервер
  • Инициализируем Node.js проект командой npm init
  • Устанавливаем необходимые пакеты командой npm install cors express http-proxy-middleware
  • Создаём файл index.js со следующим содержимым:
CORS: просто и понятно говорим про ошибки кроссдоменных запросов
  • Запускаем proxy сервер командой node index.js

  • Теперь мы можем использовать адрес и порт, указанный в proxy сервере в приложении во время разработки.
CORS: просто и понятно говорим про ошибки кроссдоменных запросов

На этом всё. Мы рассмотрели причины возникновения ошибки CORS и одно из возможных решений при локальной разработке на фронте. Надеюсь, мой материал будет вам полезен. Буду рад продолжить обсуждение темы в комментариях. Всем хорошего дня и поменьше ошибок CORS!

2222
11 комментариев

Помимо прокси сервера, для разработки можно запустить специальный инстанс браузера, в котором отключены CORS

https://alfilatov.com/posts/run-chrome-without-cors/

2
Ответить

Спасибо за статью. Расскажите, почему в случае блокировки кроссдоменных запросов корсом, запросы из постмана могут успешно обрабатываться?

2
Ответить

Насколько понимаю, cors - это требование браузера. И его можно отключить.

2
Ответить

Спасибо за статью. Было очень полезно

1
Ответить

Рисуночки класс 👍

1
Ответить

Я нормально наелся этой ошибки когда пытался сделать на ангуляре сайтик который бы показывал мне самую выгодную позицию (руб/1г белка) в Яндекс лавке. Я вообще не по фронтенду, поэтому не знаю, какие бест практики чтобы колить внешний не зависимый API из кода фронта получается? Неужели только прокси? Или бест практика не делать так на фронте в принципе?)

1
Ответить

Наконец понял как с этим справляться, а не полагаться на магию ответов stackoverflow

1
Ответить