Итак, что такое политика одинакового происхождения? Какие есть ограничения и почему это имеет смысл? Цель статьи состоит в том, чтобы охватить основы политики одинакового происхождения и новейшие методы, позволяющие обойти это ограничение.

Та же политика происхождения

Это важная концепция в модели безопасности веб-приложений. В соответствии с этой политикой веб-браузер разрешает сценариям, содержащимся на первой веб-странице, доступ к данным на второй веб-странице (или веб-службе), только если обе веб-страницы имеют одинаковое происхождение (базовый URL). См. Правило определения происхождения.

Пример: если веб-страница использует файлы cookie HTTP для поддержания аутентифицированных пользовательских сеансов, другая веб-страница (с другим источником) не может использовать эти файлы cookie для аутентификации и выполнения операций на исходном веб-сайте. На стороне клиента должно поддерживаться строгое разделение контента, предоставляемого несвязанными сайтами, чтобы предотвратить потерю конфиденциальности или целостности данных.

Исключением из этого правила является HTML-тег ‹script› или ‹img›. Размещение форм или ссылки на другие домены также возможны. Фреймы и iFrames могут отображать информацию из других доменов, но взаимодействие с этим содержимым ограничено. Например, веб-страница может загружать скрипты из совершенно другого источника, чем ее собственный (обычно используется для получения сторонней библиотеки из внешней размещенной службы), используя тег ‹script›. Но код JavaScript, загруженный из этого тега script, снова не может получить какие-либо ресурсы (или вызвать API) с любой другой веб-страницы, происхождение которой не совпадает с исходной веб-страницей, на которую он загружен.

JSONP (JSON с дополнением)

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

Идея состоит в том, чтобы использовать тег ‹script› для извлечения и выполнения контента, полученного из внешних источников. Тег Script можно использовать для получения кода Javascript из иностранного источника и его выполнения на вызывающей веб-странице. Но если извлекаемый URL-адрес возвращает данные JSON в ответ (например, типичный URL-адрес HTTP-запроса GET), то встраивание безымянного объекта javascript, как показано ниже, приведет к ошибке Javascript.

{
     “ Name”: “Neeraj”,
     “Id”: “2ae7690f45eed10c89”,
     “title”: “Admin”
}

Браузер загрузит файл ‹script›, оценит его содержимое, неправильно интерпретирует необработанные данные JSON как блок и выдаст синтаксическую ошибку. Даже если бы данные были интерпретированы как литерал объекта JavaScript, к ним не мог бы получить доступ JavaScript, запущенный в браузере, поскольку без присвоения переменной литералы объектов недоступны.

В шаблоне использования JSONP запрос URL-адреса, на который указывает атрибут src в элементе ‹script›, возвращает данные JSON с кодом JavaScript (обычно вызовом функции), обернутым вокруг него (с дополнением). Вызов функции JSONP, который отправляется обратно, и полезная нагрузка, которую получает функция, должны быть согласованы между клиентом и сервером.

По соглашению сервер, предоставляющий данные JSON, предлагает запрашивающему веб-сайту назвать функцию JSONP, обычно используя QSP обратного вызова, как показано ниже.

<script type=”application/javascript”
src=”https://www.example.com/Users/1234?callback=parseResponse">
</script>

В этом примере полученная полезная нагрузка будет:

parseResponse({“Name”: “Neeraj”, “Id”: “2ae7690f45eed10c89", “title”: “Admin”});

КОРС

CORS (Cross-Origin Resource Sharing) — это стандарт W3C, предоставляющий механизм для выполнения междоменных запросов из браузера. Поддержка CORS требует координации между сервером и клиентом. Поддерживая CORS, поставщик услуг может добавить несколько специальных заголовков ответов, которые позволяют потребителю услуг получать доступ к данным.

Для простых запросов, таких как метод HTTP GET/HEAD/POST и Content-type ‘application/x-www-form-urlencoded’, ‘multipart/form-data’, ‘text/plain’, необходимо отправить только один запрос. Но для более сложных запросов, таких как HTTP DELETE/POST, браузер должен отправить предварительный запрос с HTTP OPTIONS и только после успешного ответа отправляет фактический запрос.

К счастью, браузер выполняет большую часть тяжелой работы и при необходимости выполняет эти дополнительные запросы от имени клиента.

Monsur Hossain написал отличную статью о CORS в HTML5 Rocks, которую вы должны прочитать.



Лучший способ поиграть с CORS — использовать JavaScript fetch() API в консоли браузера и отслеживать вкладку сети, чтобы просмотреть фактический HTTP-запрос, отправленный вашим браузером.