Статьи

Ajax-запросы к другим доменам с совместным использованием ресурсов

JavaScript может выполнять запросы Ajax через объект XMLHttpRequest; эти запросы ничем не отличаются от HTTP-запросов, выполняемых браузером при вводе URL-адреса или при отправке формы. Однако запросы Ajax могут указывать только на URL-адреса в одном и том же домене (полный порт и протокол http [s]: //) страницы, где выполняется код JavaScript — в основном там, где находятся теги <script>.

Эта же политика происхождения является базовым механизмом безопасности, реализованным всеми браузерами, начиная с Netscape: она останавливает вредоносный веб-сайт, выполняющий запросы Ajax к gmail.com и крадущий ваши данные.

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

Решения

 Первыми решениями ограничений политики Same Origin были взломы, например использование собственного домена в качестве прокси : на стороне сервера легко выполнять HTTP-запросы к любому домену без ограничений. Это решение, однако, дублирует трафик, который вы должны содержать, вместо того, чтобы ориентироваться непосредственно на третье лицо.

JSONP — это старый надежный метод, использующий тег <script> для включения сценария из стороннего домена, который будет выполняться в той же области, что и текущая страница. Этот сценарий обычно просто передает данные в обратный вызов, указанный вашим собственным кодом, и, поскольку он загружается с помощью тега <script>, он работает только для запросов GET.

Cross-Origin Resource Sharing — самая современная техника, и она реализована в основных браузерах (за исключением заметного Opera). Он разрешает запросы к другим доменам для определенного подмножества URL — тех, которые возвращают HTTP-заголовок, явно разрешающий вашему домену работать с ними.

Как работает обмен ресурсами между источниками

Удаленные домены, которые хотят разрешить запросы к другим источникам, должны добавить заголовок HTTP Access-Control-Allow-Origin к своим выходным данным, для каждой страницы или для всех своих URL-адресов.

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

Access-Control-Allow-Origin: *

Или это может перечислить только разрешенные веб-сайты, разделенные пробелами. Домен должен быть завершен с http: // и с: port, где он не является значением по умолчанию (80). Домен в смысле СОП определяется как протокол, домен и порт.

Access-Control-Allow-Origin: http://google.com http://example.com

Учитывая вмешательство в заголовки HTTP целевого домена, есть два варианта использования для CORS:

  • сайты, публикующие открытые данные , которые сами добавляют заголовок. Несколько сайтов .gov делают это.
  • Сайты под вашим контролем , где вы можете добавить заголовок ко всем нужным страницам.

Поскольку CORS использует объекты XMLHttpRequest, он позволяет вам использовать один и тот же API для всех запросов (например, jQuery) и обрабатывать ошибки, как вы делаете для локальных ресурсов.

Образец кода

Эти примеры кода были протестированы с текущей версией Chrome. Я настроил виртуальный хост remotedomain на своем экземпляре Apache, указывая на другую папку на localhost.

Мои удаленные данные были опубликованы по адресу http: //remotedomain/data.php:

<?php
echo json_encode(array(
    'field' => 'value'
));

Это была страница с localhost, запрашивающая это:

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
    $('#content').load('http://remotedomain/data.php');
});
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>

Этот пример не будет работать как есть:

однако, если мы добавим заголовок для CORS к выводу из data.php:

<?php
header("Access-Control-Allow-Origin: *");
echo json_encode(array(
    'field' => 'value'
));

Мы отображаем это в div страницы запроса:

{"field":"value"}

Обратите внимание, что клиентский код не изменился, что необходимо для других подходов, таких как JSONP (хотя и хорошо поддерживается внутри jQuery и других сред).

Ресурсы

На странице Mozilla Developer Network по управлению доступом HTTP подробно рассказывается о других заголовках Access-Control, которые позволяют использовать другие варианты использования, например запросы с учетными данными. Серьезно, вы должны отправлять на developer.mozilla.org любого дурака, который отправляет вас на w3schools.com .

Enable Cors содержит инструкции по включению заголовков на разных серверах, таких как Apache и IIS, а также по добавлению их на уровне страницы с помощью PHP, ASP.NET или даже Google App Engine. В нем перечислены серии общедоступных наборов данных, уже обслуживающих контент таким способом.

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