AJAX Lite. Простой пример подгрузки части страницы.

В этой короткой статье рассматриваются базовые принципы построения web-приложения с использоваием технологии AJAX в наиболее простой и надёжной в работе форме.

Общие принципы технологии

Согласно http://ru.wikipedia.org/wiki/Ajax:

AJAX (от англ. Asynchronous JavaScript and XML – «асинхронный JavaScript и XML») – это подход к построению интерактивных пользовательских интерфейсов веб-приложений. При использовании AJAX веб-страница не перезагружается полностью в ответ на каждое действие пользователя. Вместо этого с веб-сервера догружаются только нужные пользователю данные. AJAX – один из компонентов концепции DHTML.

AJAX базируется на двух основных принципах:

  1. использование DHTML для динамического изменения содержания страницы;
  2. использование технологии динамического обращения к серверу «на лету», без

перезагрузки всей страницы полностью, например:

  • с использованием XMLHttpRequest;
  • через динамическое создание дочерних фреймов;
  • через динамическое создание тега <script>.

Модель AJAX

  1. Пользователь заходит на веб-страницу и нажимает на какой-нибудь её

элемент.

  1. Скрипт (на языке JavaScript) определяет, какая информация необходима для

обновления страницы.

  1. Браузер отправляет соответствующий запрос на сервер.
  2. Сервер возвращает только ту часть документа, на которую пришел запрос.
  3. Скрипт вносит изменения с учётом полученной информации (без полной

перезагрузки страницы).

Часто сервер передаёт не готовый HTML-код, а только данные; а HTML-элементы создаются исходя из этих данных, с использованием методов модификации DOM. При этом в качестве формата передачи данных обычно используются XML или JSON.

JSON хорош тем, что на стороне клиента его не надо обрабатывать каким-то специальным образом, достаточно выполнить вызов функции eval(). Однако, исходя из соображений безопасности, его необходимо анализировать, так как при передаче вредоносного кода функция eval() выполнит данный код.

Идеология «загрузки страницы по частям» мягко говоря не нова и до этого прекрасно реализовывалась во фреймах, которые с некоторых пор попали в опалу, по причине того, что поисковики их не любят. AJAX – любим поисковиками ничуть не более чем фреймы, впрочем в нем много того, что есть лишь дань моде и с построением удобных web-интерфейсов не связано. Рассмотрим поподробнее этапы этой модели.

Как отправлять запросы серверу

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

Создание дочернего фрейма

  1. Пользователь инициирует событие (например нажимает на ссылку)
  2. JavaScript создаёт фрейм с незначительными размерами, в src параметр которого прописывает url запроса к серверу;
  3. сервер возвращает ответ, на основе которого формируется JavaScript — код JavaScript используя объектную модель документа размещает HTML код в нужном элементе (например с помошью свойств InnerHTML или value).

Использование объекта XMLHttpRequest

  1. Пользователь инициирует событие (например нажимает на ссылку);
  2. JavaScript посылает запрос серверу через метод send() объекта класса XMLHttpRequest;
  3. сервер возвращает ответ, который доступен при обращении к свойству responseText;
  4. используя объектную модель документа, размещает HTML код в нужном элементе (например с помошью свойств InnerHTML или value).

Оба этих способа примерно одинаковы по всем параметрам и позволяют достичь примерно одного результата

  1. отослать запрос к серверу;
  2. отследить момент завершения выполнения запроса;
  3. заполнить нужный элемент HTML-кода данными.

Мой выбор 2-го варианта связан, в основном, с причиной «исторически сложилось» :-)

Как получить данные

В этом месте обычно разгорается жаркий идеологический спор. Наиболее употребимых и безпроблемным способов передачи данных между сервером и клиентом существует 2: через XML и в виде обычного HTML.

Я как правило использую обычный HTML по следующим причинам:

  1. на парсинг XML на стороне клиента уходят ресурсы, при том, что формировать XML для сервера ничем не проще, простому пользователю это видится как тормоза :-);
  2. на загрузку JavaScript-фреймворка, выполняющего сложную обработку XML-ответа идут килобайты, килобайты и килобайты. Конечно сейчас это может не так актуально, но все равно куда приятнее, когда страница стартует 1 секунду, а не 10;
  3. как правило, при «подгрузке» размер html-кода, сформированного из XML превышает его по размерам на единицы процентов, а при грамотном подходе и использовании CSS может даже быть меньше.

Пример простого AJAX-приложения

Рассмотрим пример простого AJAX — приложения, подгружающего в код основной страницы содержимое другой, при клике по ссылке. Причем подгружает его только один раз, дальше он его просто показывает и прячет.

JavaScript-«фреймворк»

Представлен файлом scripts.js, лежащим в корне сайта

// Код вызова
var call_code;
// Объект класса XMLHttpRequest
var xmlHttp;

function CallServer(item,url,reload)
{
    // Если reload - false - то страница загружается в объект только если innerHTML у него пустой
    // Запоминаем код вызова
    call_code=item;
    // Если данных ещё нет, то подгружаем их
    if ((call_code!='') &&
        ((document.getElementById(item).innerHTML=='' || reload))
       )
    {
        // Если имеем дело не с InternetExplorer
        if (window.XMLHttpRequest) {
            xmlHttp = new XMLHttpRequest();
            // Открыть соединение с сервером
            xmlHttp.open("GET", url, true);
            // Установить функцию для сервера, которая выполнится после его ответа
            xmlHttp.onreadystatechange = updatePage;
            // SПередать запрос
            xmlHttp.send(null);
        }
        // Если имеем дело с InternetExplorer(он объект XMLHttpRequest имеет
        // в виде active-X компонента XMLHTTP)
        else if (window.ActiveXObject)
        {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            // Установить функцию для сервера, которая выполнится после его ответа
            xmlHttp.onreadystatechange = updatePage;
            // Открыть соединение с сервером
            xmlHttp.open("GET", url, true);
            // SПередать запрос
            xmlHttp.send();
        }

        // Включить индикатор загрузки
        loadPage();
    }
}

//индикатор загрузки
function loadPage()
{
    document.getElementById(call_code).innerHTML= 'Загрузко...';
}

// Функция, выполняемая после ответа
function updatePage() {
  if (xmlHttp.readyState == 4) {

        if (xmlHttp.status == 200) {
            // Если код ошибки - 200 подгружем ответ сервера в элемент HTML с
            // ID=call_code
            document.getElementById(call_code).innerHTML = xmlHttp.responseText;
        } else {
            alert("Не удалось получить данные:\n" + xmlHttp.statusText);
        }

  }
}

// Функция показывает, скрывает элемент html с указанным ID
function SH(name) {
    _div = document.getElementById(name);

    if (_div.style.display == "none") _div.style.display=""; else _div.style.display="none";
}

Код основной страницы

Представлен файлом index.html, лежащим в корне сайта

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1251">
<script type="text/javascript" src="/scripts.js"></script>
</head>
<body>
<!--
При клике на ссылку в элемент с ID = content подгружется содержимое страницы
loading.php, причем только один раз - когда туда еще ничего не загружено (потому
что 3-й параметр функции CallServer = false)
-->
<a href="#" onclick="SH('content');CallServer('content','/loading.php',false);">Подгрузить</a>
<div id="content" style="display:none"></div>
</body>
</html>

Код подгружаемой страницы

Представлен файлом loading.php, лежащим в корне сайта

<?php
// Выставляем кодировку
header("Content-Type: text/html; charset=Windows-1251");
?>
Hello world

Грабли

Вот на что следует обратить внимание, тем, кто только знакомится с ajax вообще, и с XMLHttpRequest в частности:

  1. Тег script внутри подгруженного через SallServer куска не исполняется, хотя вызов javascript-функций вполне работает. Так что лучше всего будет вынести функции, как и полагается, в отдельный файл, а из подгружаемой страницы их только вызывать.
  2. Этот кусок кода в подгружаемой странице очень важен:
    <?php
    // Выставляем кодировку
    header("Content-Type: text/html; charset=Windows-1251");
    ?>

Без него в FireFox и Opera будут проблемы с кодировкой, а InternetExplorer вообще откажется с вами работать

Заключение

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


Добавить комментарий