Кросс-доменная загрузка данных с Webix

Для чего это нужно

Среди современных веб-приложений часто встречаются достаточно сложные по структуре. Нередко при создании одной страницы могут использоваться данные из множества источников, часть из которых — это сторонние библиотеки или схожие приложения, находящиеся на другом сайте. И вот здесь появляется проблема. Страница, расположенная на одном домене, не может получить доступ к данным с другого домена.

Например, если ваша страница расположенная на http://app.mydomain.com попытается загрузить данные с http://data.mydomain.com — загрузка данных не выполнится. Любой браузер блокирует такой тип загрузки данных из соображений безопасности. Более того, запрос к другому порту, например к http://app.mydomain.com:5000, будет также заблокирован. Два URL, указывающие на один и тот же домен, но на различные порты воспринимаются как URL, указывающие на различные домены.

Для любой проблемы можно найти решение. Webix использует 2 техники, которые позволяют избежать подводных камней при загрузке данных, — CORS и JSONP.

CORS

Первая техника, которую можно использовать для кросс-доменных запросов — это CORS (Cross-origin resource sharing). CORS является стандартом кросс-доменного взаимодействия данных. Правильно настроив сервер с данными, вы можете открыть доступ к данным для скриптов с других веб-доменов.

При инициировании кросс-доменного запроса современный браузер отправляет запрос, содержащий HTTP-заголовок origin. Это дефолтное поведение браузера, поэтому нам не нужно ничего менять. В качестве значения заголовка передается домен главной страницы, с которой был инициирован запрос. Например, давайте предположим, что страница, расположенная на http://app.mydomain.com пытается получить пользовательские данные с http://data.mydomain.com. Команда, отправляющая запрос, будет выглядеть следующим образом:

webix.ajax("http://data.mydomain.com/data.php", function(text, data){
table.parse(data.json());
});

Браузер автоматически включит в HTTP-запрос следующий заголовок:

Origin: http://app.mydomain.com

Теперь сервер должен отправить ответ, также содержащий специальный заголовок:

Access-Control-Allow-Origin: http://app.mydomain.com

Такой ответ информирует браузер о том, что сервер на домене data.mydomain.com дает разрешение приложению домена app.mydomain.com использовать содержащиеся на нем данные. Нужно отметить, что такой ответ не сформируется по умолчанию. Необходимо либо изменить настройки сервера, либо настроить ваше приложение таким образом, чтобы заголовок добавлялся в ответ сервера.

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

Узнать больше о конфигурации CORS можно из подробного руководства.

Резюме

Преимущества технологии CORS:

  • имеет стандартную базу
  • не требует изменений на клиентской стороне
  • не требует дополнительного кода или каких-то изменений в логике серверного кода
  • может использоваться с любым видом данных (структурированные или не структурированные)
  • может использоваться со всеми типами запросов: GET, POST, PUT, DELETE и т.д.

Есть у CORS и пара недостатков:

  • требует перенастройки сервера
  • не работает в IE8 и IE9

JSONP

Вторая техника, используемая в Webix — это JSONP (JSON with padding) или “JSON с подкладкой”. Как и в случае CORS, его можно использовать для запроса данных с сервера, расположенного на другом домене. Однако, на клиентской стороне запрос в формате JSONP имеет свои особенности. Команда, отправляющая запрос, должна быть сконфигурирована следующим образом:

webix.jsonp("http://data.mydomain.com/data.php", {}, function(data){
table.parse(data);
});

Таким образом, синтаксис команды в формате JSONP очень похож на webix.ajax-запрос, но с некоторыми отличиями. Вышеуказанная команда вызовет скрипт, переданный ей в качестве первого параметра, и загрузит таблицу с полученными с сервера данными. Кроме того, в отличие от webix.ajax, JSONP всегда возвращает данные в структурированном виде.
Для того, чтобы поддерживать данный вид запроса, код серверной стороны на data.mydomain.com тоже должен быть сконфигурирован особым образом. Посмотрите на следующую структуру:

$data = get_data_in_some_way();
$json_data = json_encode($data);

$jsonpname = $_GET["jsonp"];

header('content-type: application/json; charset=utf-8');
echo $jsonpname."(".$json_data.")";

Как видите, данные в ответе сервера “обернуты” дополнительным кодом, закодированы в формате JSON и отправлены вместе с параметром “jsonp”. Webix скрывает все технические детали обработки данных в формате JSONP, однако как на клиентской, так и на серверной стороне необходимо задать собственную логику.

Чтобы получить больше информации о том, как работает JSON, вы можете прочитать статью в Википедии.

Резюме

Преимущества JSONP:

  • работает во всех браузерах
  • не требует изменения конфигурации сервера

К недостаткам JSONP можно отнести:

  • требует специальный код на стороне клиента
  • работает только со структурированными данными
  • подвержен XSS-атакам
  • работает только с GET-запросами

Какую технику выбрать

Ответ на данный вопрос зависит от особенностей вашего проекта. Наиболее значимым отличием между техниками CORS и JSONP является поддержка старых версий IE. В случае, если такая поддержка является обязательным требованием, лучше остановить свой выбор на JSONP. В других случаях лучшим решением является CORS, поскольку он более безопасен, основывается на стандартах и требует меньше кода.