Поддержка Ajax

Автор: Анна Лысак и Татьяна Головко Дата публикации: 09.09.2011

Ничего себе! Ajax, HTML 5 и RIA? Как эти вещи работают все вместе на мобильном устройстве? Как мы знаем, Ajax — часть технологии JavaScript, так что частично уже понятно. HTML 5 для мобильных браузеров тоже в той или иной степени часть JavaScript с бонусом в виде каких-то функций разметки (новые технологии, позаимствованные мобильными браузерами из проекта HTML 5 — практически все новые JavaScript API, которые будут работать с HTML). Rich Internet Application также включают реализацию некоторых из JavaScript UI шаблонов дизайна.

Ajax особенно важен для мобильных устройств. Для мобильных браузеров возможность загрузить нужные данные без необходимости перезагрузки страницы является ключевой.

Но Ajax не входит в официальные стандарты и ситуация с его поддержкой может варьироваться в зависимости от устройства.

Если твой мобильный сайт получает контент при помощи Ajax, то тебе стоит прислушаться к рекомендациям Google по поисковой оптимизации. Подробнее об этих рекомендациях можешь узнать на сайте http://code.google.com/web/ajaxcrawling.

Для начала давай выясним, в каких браузерах поддерживается нативный объект XMLHttpRequest (см. таблица 9.1). Из-за предполагаемых проблем с безопасностью, междоменные запросы в мобильных браузерах не поддерживаются, но ты можешь легко решить эту проблему при помощи простого прокси на своем сервере.

Табл. 9.1. Таблица поддержки XMLHttpRequest
Браузер/ Платформа Поддержка XMLHttpRequest
Safari Да
браузер Android Да
Symbian/S60 Да с 3-го выпуска
Nokia Series 40 Нет до 6-го выпуска
webOS Да
BlackBerry Нет до версии 4.6
NetFront Нет до версии 3.5
Internet Explorer Да с Windows Mobile 5
Motorola Internet Browser Нет
Opera Mobile Да с версии 8.0
Opera Mini Да с версии 3.0

Поддержка этого объекта подразумевает поддержку следующих свойств и методов:

  • open;
  • abort;
  • send;
  • onreadystatechange;
  • readyState;
  • status;
  • responseText;

Парсинг XML

Свойство (стандартное для декстопного Ajax), которое мы взяли из предыдущего списка — responseXML. Все потому, что парсинг XML — более сложный механизм внутри браузера и с здесь могут возникнуть некоторые проблемы. Первое различие, с которым мы должны разобраться — как браузеры обрабатывают пробел в тегах. Давай посмотрим на простой пример:

<node>
	<subnode />
</node>

Некоторые браузеры поймут предыдущий код как узел с одним дочерним элементом. Другие посчитают, что здесь есть три дочерних элемента: текстовый узел с пробелом и символом новой строки, подузел и еще один текстовый узел. С этими небольшими различиями в обработке может довольно трудно разобраться, когда о них не знаешь. В таблице 9.2 показано какие браузеры и как именно поддерживают парсинг XML.

Табл. 9.2. Таблица поддержки парсинга XML
Браузер/ Платформа Поддержка парсинга XML Пробелы как дочерние элементы
Safari Да Да
браузер Android Да Да
Symbian/S60 Да Да
Nokia Series 40 Нет до 6-го выпуска Да
webOS Да Да
BlackBerry Нет до версии 4.6 Да
NetFront Да с версии 3.6 Да
Internet Explorer Да Нет
Motorola Internet Browser Нет Да
Opera Mobile Да Да
Opera Mini Да, на сервере Да

Парсинг JSON

JavaScript Object Notation (JSON) — самое легкое (по весу) решение Ajax, потому что позволяет нам для доступа к объекту использовать запись через точку, а не парсить DOM, как, например, в XML. В JSON мы получаем текст как responseText и преобразовываем его в объект при помощи eval. А теперь первый вопрос: как работает eval в мобильных устройствах?

Нам нужно протестировать поддержку eval для объектов JSON по стандарту strict и de facto используемым стандартом, который лучше всего поддерживается в большинстве браузеров. Различия между этими двумя вариантами видно в следующем примере кода, а в таблице 9.3 — информация, в каких браузерах поддерживается парсинг JSON:

	// Стандарт Strict
	var obj = {
	'name': 'John',
	'surname': 'Doe'
	}
	// Фактический стандарт
	var obj = {
	name: 'John',
	surname: 'Doe'
	}
Табл. 9.3. Таблица поддержки парсинга JSON
Браузер/ Платформа eval на JSON (strict и de facto стандарты)
Safari Да
браузер Android Да
Symbian/S60 Да
Nokia Series 40 Нет до 6-го выпуска
webOS Да
BlackBerry Нет до версии 4.6
NetFront Да
Internet Explorer Да
Motorola Internet Browser Да
Opera Mobile Да
Opera Mini Да

В low- и mid-end устройствах, где есть поддержка Ajax, не рекомендуется создавать одновременно более двух соединений с сервером. Вообще, если возможно, старайся сводить к минимуму количество одновременных подключений.

JSONP и Lazy Loading (отложенная загрузка)

JSON с Padding (JSONP) — современный способ получить доступ к контенту стороннего домена, обходя междоменные проблемы Ajax-запросов. Во многих общедоступных веб-сервисах предлагается использовать именно JSONP для связи со сторонними серверами.

В JSONP используется тег <script>, сгенерированный при помощи JavaScript, который содержит URL с параметром, заданным нами для локальной функции обратного вызова, которая вызывается, когда загружается и выполняется скрипт (и извлекаемые им данные).

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

Для работы JSONP необходимо, чтобы браузер поддерживал возможность динамической вставки тега script. Если эта возможность поддерживается, браузер определит новый DOM script элемент и автоматически загрузит и выполнит его. И так как этот скрипт вызывает твою функцию с данными, ты сможешь получать информацию (данные) со стороннего сервера.

Современные библиотеки JavaScript вроде jQuery поддерживают запросы JSONP без работы с DOM. Ты можешь применять $.getJSON с параметром для замены запроса Ajax на запрос JSONP.

Как правило, сервер может использовать URL в формате JSONP. Например:

	http://api.thirdpartyserver.domain/<jsonp_script>?<callback>=<our_function>

Сервер ответит примерно так:

	<our_function>( {<json_data>} );

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

function doJSONP() {
	var head = document.getElementsByTagName('head')[0];
	var script = document.createElement('script');
	script.type = 'text/javascript';
	script.src = 'http://mobilexweb.com/tests/jsonp?cb=finished';
	head.appendChild(script);
}

В таблице 9.4 показано, как этот прием работает в различных мобильных браузерах. В некоторых браузерах поддерживается событие onload, которое может быть применено к скрипту и будет выполняться, когда он уже будет загружен. В целом, JSONP не нуждается в использовании этого события, так как в том же самом URL уже есть определение обратного вызова, но в браузерах с наличием с соответствующей поддержки данное событие может быть весьма полезно для отложенной загрузки.

Табл. 9.4. Таблица поддержки динамической вставки тега script и события onload
Браузер/ Платформа Поддержка динамической вставки тега script Поддержка onload
Safari Да Да
браузер Android Да Да
Symbian/S60 Да Да
Nokia Series 40 Нет до 6-го выпуска
webOS Да Да
BlackBerry Да с версии 4.6 Нет
NetFront Да Нет
Internet Explorer Нет
Motorola Internet Browser Нет Нет
Opera Mobile Да Да и onreadystatechange
Opera Mini Нет

Техника Comet

Comet — новая модель веб-приложения — предоставляет альтернативный вариант отправки запроса на сервер, который используется для периодической проверки обновлений данных на сервере (например, для новостей, чатов и подобных задач). При помощи модели Comet мы можем посылать долгоживущие HTTP запросы, которые остаются открытыми, пока сервер не ответит клиенту.

Например, когда информация об адресе почтового ящика находится в открытом доступе, ты, скорее всего, захочешь иметь возможность каждые Х секунд проверять его на наличие новых писем. Метод Comet позволяет нам эмулировать своего рода push-технологию, когда вместо того, чтобы самим каждые Х секунд проверять наличие новых сообщений, мы делаем запрос только один раз и он остается открытым, пока сервер не сообщит, что у него есть новые данные. В результате на протяжении довольно длительного времени HTTP соединения остаются в открытом состоянии. Мы рассмотрели только один вид техники Comet, есть и другие, но они уже не очень надежны.

Palm, BlackBerry и Apple предлагают разработчикам push-сервисы: ты можешь перенаправить сообщения или контент со своих серверов на их и уже оттуда информация будет доставлена непосредственно на устройство. К сожалению, такие функции недоступны для Palm и Apple веб-приложений.

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

Если ты используешь подвешенное соединение на сервере в качестве решения для Comet, помни, что адекватные результаты будут только в Symbian 5-й версии, мобильном Safari, Windows Mobile 6.5 и Android. В Series 40 6-го поколения и в других устройствах браузер подвисает с запросом и, в результате, пользователь не может даже кликнуть по ссылке.

Есть также некоторые Adobe Flash решения, суть работы которых в открытии сокетов для получения новостей с сервера. Работать такое решение будет только с Flash Player 10.1 и WiFi. С 3G уже возникнут проблемы. И здесь нужно быть внимательным и не злоупотреблять этим методом из-за его повышенной энергоемкости.

Куда дальше