Создание динамических веб-страниц на стороне клиента с помощью AJAX
AJAX (Asynchronous JavaScript and XML) - это концепция использования нескольких смежных технологий, ориентированная на разработку высокоинтерактивных приложения, быстро реагирующих на действия пользователя, выполняющих большую часть работы на стороне клиента и взаимодействующих с сервером посредством внеполосных обращений.
Внеполосным обращением называется запрос к серверу, который приводит к оперативному обновлению страницы вместо ее замены. Внеполосный вызов HTTP - это HTTP запрос, который выдается за пределами встроенного модуля, обеспечивающего отправку форм HTTP. Вызов инициируется событием, связанным со страницей HTML и обслуживается компонентом-посредником, обычно объектом XmlHttpRequest.
Популярность AJAX связана с появлением сервиса Google Suggest в 2005 году. Данный сервис на основе объекта XMLHttpRequest предоставляет в распоряжение пользователя достаточно динамический веб-интерфейс. В процессе ввода символов пользователем в поле поискового запроса JavaScript отправляет их на сервер и получает от него список подсказок:
AJAX применяется для разработки веб-приложений, к которым предъявляются следующие требования:
- Приложение должно передавать пользователям свежие данные, полученные с сервера.
- Новые данные должны интегрироваться в существующую страницу без ее полного обновления.
Для работы с такими приложениями в браузере, необходимо, чтобы он соответствовал требованиям:
- Поддержка посредников (для внеполосных вызовов HTTP ). Обычно реализуется в форме объекта XmlHttpRequest.
- Поддержка обновляемой модели DOM.
Объект XmlHttpRequest представляет собой компактную объектную модель для отправки сценарием обращений HTTP в обход браузера. Клиентский код сценария не может влиять на процесс размещения запроса и результат отправки запроса. XmlHttpRequest позволяет сценарию отправлять HTTP запросы и обрабатывать полученные ответы.
В качестве формата передачи данных обычно используются JSON или XML.
JSON
JSON (JavaScript Object Notation) - текстовый формат обмена данными, основанный на JavaScript и обычно используемый именно с этим языком. Несмотря на происхождение от JavaScript, формат считается языково-независимым и может использоваться практически с любым языком программирования. Для многих языков существует готовый код для создания и обработки данных в формате JSON.
JSON строится на двух структурах данных:
- Набор пар имя/значение. В различных языках это реализовано как объект, запись, структура, словарь, хэш-таблица, список с ключом или ассоциативный массив.
- Пронумерованный набор значений. Во многих языках это реализовано как массив, вектор, список или последовательность.
В JSON используются следующие формы данных:
- Объект - это неупорядоченное множество пар имя/значение, заключенное в фигурные скобки { }. Между именем и значением стоит символ ":", а пары имя/значение разделяются запятыми.
- Массив (одномерный) - это множество значений, имеющих порядковые номера (индексы). Массив заключается в квадратные скобки [ ] . Значения отделяются запятыми.
- Значение может быть строкой в двойных кавычках, или числом, или true, или false, или null, или объектом, или массивом. Эти структуры могут быть вложены друг в друга.
- Строка - это упорядоченное множество из нуля или более символов юникода, заключенное в двойные кавычки, с использованием escape-последовательностей начинающихся с обратной косой черты ( backslash ). Символы представляются простой строкой.
Следующий пример показывает JSON -представление объекта, описывающего преподавателя.
{ "firstName": "Сергей", "lastName": "Иванов", "profile": { "position": "доцент, к.ф.-м.н.", "department": "кафедра информационных систем", "age": 40 }, "subjects": [ "интернет-технологии", "информационные технологии" ] }
Использование JSON в AJAX
Следующий фрагмент Javascript кода показывает, каким образом клиент может использовать XMLHttpRequest, чтобы запрашивать с сервера объект в формате JSON. (Предполагается, что серверная часть программы выполняет запросы в формате JSON ).
var the_object; var http_request = new XMLHttpRequest(); http_request.open( "GET", url, true ); http_request.send(null); http_request.onreadystatechange = function () { if ( http_request.readyState == 4 ) { if ( http_request.status == 200 ) { the_object = eval( "(" + http_request.responseText + ")" ); } else { alert( "There was a problem with the URL." ); } http_request = null; } };
В данном примере использование XMLHttpRequest не является универсальным. Полезность XMLHttpRequest ограничивается политикой ограничения домена: URL ответа на запрос должен принадлежать тому же DNS домену, что и сервер, на котором находится страница, содержащая запрос.
ASP.NET AJAX
Microsoft .NET предоставляет в распоряжение разработчиков свою реализацию AJAX технологии - ASP.NET 2.0 AJAX.
С архитектурной точки зрения, инфраструктура ASP.NET 2.0 AJAX состоит из двух элементов:
- Библиотека клиентских сценариев (реализована на JavaScript ). Работает в любом современном браузере.
- Набор серверных расширений. Полностью интегрируется с серверными службами и управляющими элементами ASP.NET. Разработчики могут создавать веб-страницы с расширенной функциональностью, используя практически такую же методику, которая используется при разработке серверных страниц ASP.NET.
Пример AJAX приложения
Рассмотрим пример системы, имитирующей работу сервиса Google Suggest на основе AJAX.
Предполагается, что пользователь может вводить в текстовое поле формы название автомобильной марки, получая при этом динамически список вариантов названий, соответствующих уже введенным символам, без перезагрузки страницы.
Начнем с веб-страницы:
<html> <head> <script src="chint.js"></script> </head> <body> <form> First Name: <input type="text" id="txt1" onkeyup="showHint(this.value)"> </form> <p>Suggestions: <span id="txtHint"></span></p> </body> </html>
Как видно из кода, при наступлении события onkeyup (отжатие клавиши) вызывается обработчик showHint().
В файле chint.js имеется следующий код обработчика:
var xmlHttp; function showHint(str) { if (str.length==0) { document.getElementById("txtHint").innerHTML=""; return; } xmlHttp=GetXmlHttpObject(); if (xmlHttp==null) { alert ("Your browser does not support AJAX!"); return; } var url = "ghint.php"; url = url + "?q=" + str; url = url + "&sid=" + Math.random(); xmlHttp.onreadystatechange = stateChanged; xmlHttp.open("GET", url, true); xmlHttp.send(null); } function stateChanged() { if (xmlHttp.readyState==4) { document.getElementById("txtHint").innerHTML = xmlHttp.responseText; } } function GetXmlHttpObject() { var xmlHttp=null; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } } return xmlHttp; }
Из кода видно, что каждый раз, когда вводится символ, вызывается функция-обработчик. Если при этом содержимое текстового поля формы непустое ( str.length > 0 ), функция выполняет следующие действия:
- Формируется url для отправки веб-серверу
- Добавляется значение параметра q, равное содержимому текстового поля, к url
- Добавляется к url случайное число для предотвращения кеширования
- Создается объект XMLHTTP, при этом указывается функция ( stateChanged ) подлежащая исполнению при наступлении события ввода символа
- Открывается объект XMLHTTP с указанным значением url
- Отправляется HTTP запрос веб-серверу
Если поле ввода пустое, происходит очистка содержимого раздела txtHint на веб-странице.
Ключевым моментом в данной системе является использование объекта XMLHttpRequest.
Данный объект по-разному создается в различных браузерах. Так, Internet Explorer для этого использует ActiveXObject, в то время как остальные браузеры используют встроенный в JavaScript объект XMLHttpRequest.
Для поддержки работы системы в разных браузерах использован оператор "try-catch".
- Сначала делается попытка создать объект XMLHttpRequest для браузеров Firefox, Opera или Safari:
xmlHttp = new XMLHttpRequest().
- В случае неудачи, делается следующая попытка создания объекта для Internet Explorer 6.0+ :
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP").
- Если это также не удается, то делается попытка создания объекта уже для Internet Explorer 5.5+ :
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP").
- В случае, если ни одна из этих попыток не принесла успеха, выдается сообщение об отсутствии поддержки AJAX браузером.
На веб-сервере в файле с именем ghint.php размещен следующий PHP сценарий:
<?php header("Cache-Control: no-cache, must-revalidate"); // Прошедшая дата header("Expires: Mon, 1 Sep 2008 07:30:00 GMT"); // Инициализация массива названий $a[]="Audi"; $a[]="BMW"; $a[]="Buick"; $a[]="Chevrolet"; $a[]="Citroen"; $a[]="Dodge"; $a[]="Ferrari"; $a[]="Fiat"; $a[]="Ford"; $a[]="Honda"; $a[]="Hyundai"; $a[]="Cherokee"; $a[]="Cherry"; $a[]="Lada"; $a[]="Lamborghini"; $a[]="Lincoln"; $a[]="Mazda"; $a[]="Mercedes"; $a[]="Mitsubishi"; $a[]="Nissan"; $a[]="Opel"; $a[]="Peugeot"; $a[]="Plymoth"; $a[]="Pontiac"; $a[]="Renault"; $a[]="Rover"; $a[]="Saab"; $a[]="Subaru"; $a[]="Suzuki"; $a[]="Toyota"; $a[]="Volkswagen"; $a[]="Volvo"; //получение параметра q из URL $q = $_GET["q"]; //поиск соответствий из массива если длина q > 0 if (strlen($q) > 0) { $hint = ""; for($i = 0; $i<count($a); $i++) { if (strtolower($q) == strtolower(substr($a[$i],0,strlen($q)))) { if ($hint == "") { $hint=$a[$i]; } else { $hint=$hint." , ".$a[$i]; } } } } // Возврат строки "нет вариантов" если соответствий не найдено // либо найденное соответствие if ($hint == "") { $response = "no suggestion"; } else { $response = $hint; } //вывод результата echo $response; ?>
На скриншоте показана работа в браузере с веб-страницей ghint.html, использующей AJAX: