В интерактивности - статические html сайты - это прошлое. Динамические с использованием CGI (или модулей сервера, например Apache) и баз данных, когда сервер при отправки формы формирует страницу и показывает ее после обновления - чуть современней, но все же во многих областях, где требуется практически сопостовимая с десктопными приложениями интерактивность - так же угасают. На смену приходят интерактивные функциональные программы, в полной мере взаимодействующие с пользователем; информация, полученная от сервера практически мгновенно отображается на экране без перезагрузке страницы. Речь я виду об AJAXe, что в расшифровке "асинхронный JavaScript и XML" (термин ввел Джесс Гарретт). А если более подробно, то - "асинхронный JavaScript + CSS + DOM + XMLHttpRequest".
Методы объекта XMLHttpRequest
Все нижеизложанные методы и свойства - общие для Internet Explorer 5, Mozilla, Netscape 7, и соответственно, использовать их можно безопасно.
abort() обрывает текущий запрос
getAllResponseHeaders() возвращает полный набор заголовков ответа (названий и значений) в виде строки
getResponseHeader(<headerLabel>) возвращает строковое значение заголовка, название которого указано в параметре .
setRequestHeader(<label>, <value>) Установка в отправляемом запросе заголовка <label> со значением <value>
Свойства объекта XMLHttpRequest
onreadystatechange событие, возникающее при смене статуса объекта
readyState значения статуса (integer), может принимать следующие значения: 0 = неинициализирован (uninitialized); 1 = "идет загрузка" (loading); 2 = "загружен" (loaded); 3 = "интерактивен" (interactive) 4 = "выполнен" (complete)
responseText строка с возвращенными сервером данными
responseXML DOM-совместимый объект-документ с возвращенными сервером данными
status стандартный HTTP код статуса, например 404 (для "Not Found") или 200 (для "OK")
statusText текстовое сообщение статуса
Здесь все необходимые свойства и методы этого объекта, которые помогут нам решить наш таск. Опишем последовательность наших действий:
Алгоритм:
1. Создание экземпляра объекта XMLHttpRequest. 2. Объявление обработчика события onreadystatechange нашего экземпляра . 3. Открытие соединения с указанием типа запроса, URL и других параметров. 4. Посыл запроса.
Алгоритм незамысловат, но, учитывая кое-какие нюансы (и учитывая, что мы учимся :)), конечно же, рассмотрим его подробней:
Итак, пункт первый - создание экземпляра объекта. Вот здесь всплывает особенность обеспечения кроссбраузерности. Конструкция создания объекта различна: в IE 5+ она реализована через ActiveXObject, а в остальных браузерах (Mozilla, Netscape и Safari) — как встроенный объект типа XMLHttpRequest.
Для Internet Explorer:
var request = new ActiveXObject(Microsoft.XMLHTTP);
Для всех остальных:
var request = new XMLHttpRequest();
Таким образом, чтобы обеспечить кроссбраузерность, нужно лишь проверять наличие объектов window.XMLHttpRequest и window.ActiveXObject и применять соответствующий вызов создания экземпляра.
Далее по плану - создание обработчика событий и открытие соединения. Это весьма просто:
Здесь мы используем метод GET, хотя можно и POST; в общем виде это выглядет так: request.open(<"GET""POST"...>, <url>, <asyncFlag>);. Функцию, являющуюся обработчиком события onreadystatechange (в нашем случае это функция - processRequestChange()), мы должны определить сами.
Ну и последний пункт - посыл запроса - метод send() (для версии без ActiveX в качестве параметра нужно передать null).
// для IE request.send();
// для остальных request.send(null);
После запуска метода send() начинает работать вышеуказанный обработчик события onreadystatechange. Собственно, этот обработчик - основная часть программы. В нем обычно перехватываются все возможные коды состояния запроса и вызываются соответствующие действия, а также перехватываются возможные ошибки.
Исходя из всего вышесказанного, JavaScript код будет примерно следущим:
var request;
/** * Load XMLDoc function * Здесь в качестве параметра url при вызове мы должны указать * backend-скрипт, который, собственно, и получит данные с сервера */
function doLoad(url) { if (window.XMLHttpRequest) { request = new XMLHttpRequest(); request.onreadystatechange = processRequestChange; request.open(GET, url, true); request.send(null); } else if (window.ActiveXObject) { request = new ActiveXObject(Microsoft.XMLHTTP); if (request) { request.onreadystatechange = processRequestChange; request.open(GET, url, true); request.send(); } } }
/** * Get request state text function */ function getRequestStateText(code) { switch (code) { case 0: return Uninitialized.; break; case 1: return Loading...; break; case 2: return Loaded.; break; case 3: return Interactive...; break; case 4: return Complete.; break; } }
/** * Event on request change * Собственно, обработчик события onreadystatechange. * Здесь мы, в зависимости от состояния запроса, * будем скрывать / показывать слои Загрузка данных, * само поле данных и т.д. */ function processRequestChange() { document.getElementById(resultdiv).style.display = none; document.getElementById(state).value = getRequestStateText(request.readyState); abortRequest = window.setTimeout(request.abort();, 10000); // если выполнен if (request.readyState == 4) { clearTimeout(abortRequest); document.getElementById(statuscode).value = request.status; document.getElementById(statustext).value = request.statusText; // если успешно if (request.status == 200) { document.getElementById(resultdiv).style.display = block; document.getElementById(responseHTML).innerHTML = request.responseText; } else { alert(Не удалось получить данные:n + request.statusText); } document.getElementById(loading).style.display = none; } // иначе, если идет загрузка или в процессе - показываем слой Загружаются данные else if (request.readyState == 3 request.readyState == 1) { document.getElementById(loading).style.display = block; } }
Теперь HTML-формы нашего примера:
<input type=text id=search value=Введите первые буквы ника onFocus=this.value=; document.getElementById(resultdiv).style.display=none; /> <input type=button value=Поиск onClick=doLoad(ajaxsearch.php?search=+document.getElementById(search).value); /><br /><br />
Обратите внимение на фрагмент, выделенный зеленным цветом - событие onClick кнопки "Поиск". Мы вызываем функицю doLoad(...), в качестве параметра которой передаем адрес backend-скрипта, выполняющего поиск в базе зарегистрированного пользователя. О backend-скрипе чуть позже, имя его мы определили как ajaxsearch.php. Также GET-параметром скрипту мы передаем переменную search, со значением, взятым из поля ввода для ника.
И, как было сказано выше, объявим дополнительные HTML-элементы (в нашем случае - это невидимые слои) для отображения полученного содержимого и окна загрузки с возможностью отмены:
Ну что ж, с frontendом разобрались, переходим к backendу - скрипт ajaxsearch.php. И вновь мы сталкиваемся с небольшими нюансами: для того, чтобы PHP-скрипт корректно работал с XMLHttpRequest, он (скрипт) должен посылать ряд заголовков. А именно: тип содержимого и его кодировку (особенно важно, если вы работаете с кириллицей), а также параметры кеширования — любое кеширование должно быть отключено (ну это и понятно - необходимо иметь свежую информацию).
И еще одна особенность: если вы будете выводит данные в формате text/plane (в нашем случае - text/html, поэтому нас это не каснется, но все же - чтобы знать), помните, что спецсимволы такие как n, t, r и т.д., обрабатываются по умолчанию только в строках с двойными кавычками:
// т.е. правильно так print MessagenFrom AJAX;
// а не так! print MessagenFrom AJAX;
Ну и теперь весьма банальный PHP-скрипт получения данных из базы (а банальный, потому что предполагается, что у вас уже есть навыки работы с базами данных в PHP). Вид скрипта следующий (в найденых никах мы подсвечиваем буквы запроса красным цветом и выводим все это в виде таблицы):
/** * Коннектимся к базе, выполняем * запрос, получаем результат */
@mysql_connect($dbhost, $dblogin, $dbpassword) or die(Unable to connect to database..); @mysql_select_db(MYDATABASE) or die(Unable to select database); $sql = SELECT * FROM users WHERE nick LIKE %.$_GET[search].% ORDER BY nick; $result = mysql_query($sql);
print Найдено по запросу: .mysql_num_rows($result);