Главная страница статей --> Хитрости при программировании php, заметки по базам данных

XMLHttpRequest (AJAX) - отправка и обработка ответов http-запросов с помощью JavaScript.

Источник: realcoding.net

В интерактивности - статические html сайты - это прошлое. Динамические с использованием CGI (или модулей сервера, например Apache) и баз данных, когда сервер при отправки формы формирует страницу и показывает ее после обновления - чуть современней, но все же во многих областях, где требуется практически сопостовимая с десктопными приложениями интерактивность - так же угасают. На смену приходят интерактивные функциональные программы, в полной мере взаимодействующие с пользователем; информация, полученная от сервера практически мгновенно отображается на экране без перезагрузке страницы. Речь я виду об AJAXe, что в расшифровке "асинхронный JavaScript и XML" (термин ввел Джесс Гарретт). А если более подробно, то - "асинхронный JavaScript + CSS + DOM + XMLHttpRequest".

Методы объекта XMLHttpRequest


Все нижеизложанные методы и свойства - общие для Internet Explorer 5, Mozilla, Netscape 7, и соответственно, использовать их можно безопасно.

abort()
обрывает текущий запрос

getAllResponseHeaders()
возвращает полный набор заголовков ответа (названий и значений) в виде строки

getResponseHeader(<headerLabel>)
возвращает строковое значение заголовка, название которого указано в параметре .

open(<method>, <URL> [, <asyncFlag>[, <userName>[, <password>]]])
Присвоение параметров (метода, URL, и других) текущему запросу.

send(<content>)
Посылает запрос

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 и применять соответствующий вызов создания экземпляра.

Далее по плану - создание обработчика событий и открытие соединения. Это весьма просто:

request.onreadystatechange = processRequestChange;
request.open(GET, url, false);

Здесь мы используем метод 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 />

Дополнительная информация о выполнении запроса:<br /><br />
<
table>
  <
tr>
    <
td>Состояние запроса:</td>
    <
td><input type=text id=state disabled=true /></td>
  </
tr>
  <
tr>
    <
td>Код статуса:</td>
    <
td>
      <
input type=text id=statuscode disabled=true />
      <
input type=text id=statustext disabled=true />
    </
td>
  </
tr>
</
table>

Обратите внимение на фрагмент, выделенный зеленным цветом - событие onClick кнопки "Поиск". Мы вызываем функицю doLoad(...), в качестве параметра которой передаем адрес backend-скрипта, выполняющего поиск в базе зарегистрированного пользователя. О backend-скрипе чуть позже, имя его мы определили как ajaxsearch.php. Также GET-параметром скрипту мы передаем переменную search, со значением, взятым из поля ввода для ника.

И, как было сказано выше, объявим дополнительные HTML-элементы (в нашем случае - это невидимые слои) для отображения полученного содержимого и окна загрузки с возможностью отмены:

<div id=resultdiv style=display: none;>
 
Резульаты поиска:
  <
span id=responseHTML></span>
</
div>

<
div id=loading
 
style=
    position: absolute;
    top: 450px;
    left: 550px;
    display: none;
    width: 125px;
    height: 40px;
    font-family: Verdana;
    font-size: 11pt;
    border: 1px solid #BBBBBB;
    background: #EEEEEE;
    padding: 5px 5px 5px 5px;
 
>
 
Loading data...
  <
div id=canselloading
   
style=
      background: red;
      border: 1px solid #000000;
      color: #FFFFFF;
      padding: 2px 2px 2px 2px;
      cursor: pointer;
   
   
onClick=
      request.abort();
      document.getElementById(loading).style.display = none;
      return false;
   
 
>Cansel
 
</div>
</
div>

Ну что ж, с frontendом разобрались, переходим к backendу - скрипт ajaxsearch.php. И вновь мы сталкиваемся с небольшими нюансами: для того, чтобы PHP-скрипт корректно работал с XMLHttpRequest, он (скрипт) должен посылать ряд заголовков. А именно: тип содержимого и его кодировку (особенно важно, если вы работаете с кириллицей), а также параметры кеширования — любое кеширование должно быть отключено (ну это и понятно - необходимо иметь свежую информацию).

Послать эти заголовки можно, примерно, так:

header(Content-type: text/html; charset=windows-1251);
header(Cache-Control: no-store, no-cache, must-revalidate);
header(Cache-Control: post-check=0, pre-check=0, false);

И еще одна особенность: если вы будете выводит данные в формате text/plane (в нашем случае - text/html, поэтому нас это не каснется, но все же - чтобы знать), помните, что спецсимволы такие как n, t, r и т.д., обрабатываются по умолчанию только в строках с двойными кавычками:

// т.е. правильно так
print MessagenFrom AJAX;

// а не так!
print MessagenFrom AJAX;

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

<?php
 
 
 
/**
  * Посыл заголовков
  */
 
 
header(Content-type: text/plain; charset=windows-1251);
 
header(Cache-Control: no-store, no-cache, must-revalidate);
 
header(Cache-Control: post-check=0, pre-check=0, false);
 
 
 
/**
  * Хост, логин и пароль базы данных
  * (вам, естественно, нужно заменить на свои значения)
  */
 
 
$dbhost = localhost;
 
$dblogin = root;
 
$dbpassword = root;
 
 
 
/**
  * Коннектимся к базе, выполняем
  * запрос, получаем результат
  */
 
 
@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);
 
 
 
/**
  * Если есть ряды, выводим таблицу
  */
 
 
if (mysql_num_rows($result) > 0) {
    print
<table>;
    print
<tr>;
    print
<td>NickName</td>;
    print
<td>RealName</td>;
    print
<td>E-mail</td>;
    print
</tr>;
   
   
$get = $_GET[search];
   
    while (
$row = mysql_fetch_array($result)) {
      print
<tr>;
      print
<td>;
      print (
$row[unick] ? preg_replace(/($get)/i, <font color=red>\1</font>, $row[unick]) : &nbsp;);
      print
</td>;
      print
<td>($row[urealname] ? $row[urealname] : &nbsp;)</td>;
      print
<td>$row[umail]</td>;
      print
</tr>;
    }
    print
</table>;
  }
 
?>

Ну вот, друзья, собственно, и все на сегодня.



Похожие статьи:
- ADODB – русская документация (часть 1)
- Хранение древовидных структур в Базах данных (Nested Sets)
- Обработка запросов к БД при помощи PEAR::XML
- Дополнительные возможности JpGraph
- Установка и конфигурация веб сервера Apache с поддержкой PHP, JSP и MySQL на Windows XP
- Установка и конфигурация веб сервера Apache с поддержкой PHP, JSP и MySQL на Windows XP
- Парсинг на Perl
- Perl & XML. Библиотека программиста
- Генерация контента сайта с использованием Template Toolkit
- Использование модуля для работы с шаблонами. Часть 2.
- Модуль Apache mod_rewrite
- Модуль Apache mod_rewrite
- Включите графику!!!


Оглавление | Обсудить на форуме | Главная страница сайта | Карта сайта |

Контакты
Редакция:
[0.002]