понедельник, 15 августа 2011 г.

ExtJS: разработка интерфейса независимо от источников данных. Кросс-доменный AJAX для загрузки хранилищ

Удаленные источники для хранилищ ExtJS - это источники, расположенные в другом домене или, как их еще называют, кросс-доменные источники. Вероятно, вы знаете о том, что традиционные XMLHttpRequest запросы (известные в народе как AJAX запросы) имеют ряд ограничений, связанных в первую очередь с безопасностью - в частности, XMLHttpRequest запросы могут быть посланы только к адресу с одноименным протоколом, доменом и портом по отношению к запрашивающей странице. Таким образом, нельзя сделать традиционный AJAX запрос с сайта site1.com к сайту site2.com.

Тем не менее, такая необходимость часто возникает, в таких случаях используется так называемый cross-domain  (кросс-доменный) AJAX. Стоит отметить, что непосредственно к AJAX эти технологии уже не относятся, название в данном случае - не более, чем дань традиции. О методах, используемых в кросс-доменных запросах, можно почитать, например, в статье на javascript.ru.

Одной из проблем разработки интерфейсов на ExtJS является зависимость от динамически загружаемых данных: фактически, большинство компонентов фреймворка используют те или иные данные, получаемые при помощи AJAX запросов. Например, так выглядит традиционное описание хранилища:

myStore = new Ext.data.JsonStore({
    url:    'getUsers',
    method: 'POST',
    root: 'items',
    fields: [{name:"id"},{name:"name"}]
});

URL, указанный первым параметром, ссылается на страницу того же домена, в котором должна находиться разрабатываемая страница, иначе AJAX запрос на загрузку данных не сможет быть произведен. Таким образом, разрабатываемая html страница и javascript код в ее составе должны быть частью домена-источника данных. Это не всегда удобно и не всегда возможно.

Использование кросс-доменных запросов в таких случаях - отличное решение. Посмотрите, как просто можно заставить работать ExtJS приложение с данными любого домена:

myStore = new Ext.data.JsonStore({
    proxy: new Ext.data.ScriptTagProxy({
            url:    'http://vasilij.com/getUsers',
    }),
    method: 'POST',
    root: 'items',
    fields: [{name:"id"},{name:"name"}]
});

В код сервлета необходимо добавить отслеживание GET параметра callback. Дело в том, что при использовании ScriptTagProxy, ExtJS добавляет в строку запроса параметр callback, таким образом, что в нашем случае запрос будет иметь вид:

http://vasilij.com/getUsers&callback=stcCallback10

Возвращаемый JSON должен быть обернут в функцию, название которой соответствует переданному параметру callback. В случае сервлета:

String callback = request.getParameter("callback");
if (callback == null){
  response.setContentType("text/javascript");
  out.println(jsonString);
}
else{
  response.setContentType("application/x-json");
  out.println(callback.concat("(").concat(jsonString).concat(")"));
}

Таким образом, при отсутствии callback параметра в строке запроса возвращается обычный JSON, в противном случае JSON оборачивается в функцию.

После внесения в код приложения описанных изменений можно разрабатывать интерфейс абсолютно независимо от всей остальной части приложения; сервлеты-поставщики данных могут находиться в любом домене, и даже простая html страница на рабочем столе с подключенным ExtJS сможет получать данные и корректно их обрабатывать и отображать. После окончания процесса разработки и тестирования можно заменить Ext.data.ScriptTagProxy на Ext.data.HttpProxy для использования AJAX запросов.

Приятного кодинга вам!

Комментариев нет:

Отправить комментарий