AJAX и jQuery. Динамическое обновление контента. Основы (изменения от 03.01.2012)

В данной статье речь пойдет о том, что же такое AJAX и jQuery и будут рассмотрены примеры, как их использовать.

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

jQuery - JavaScript-framework, библиотека, позволяющая более удобно использовать некоторые возможность Javascript, такие как: создание визуальных эффектов, обработка событий, работа с DOM и поддержка AJAX.

Скачать последнюю версию jQuery и подробно ознакомиться со всеми возможностями можно на сайте разработчика: http://www.jquery.com/

В данной статье мы будем рассматривать только одну функцию библиотеки jQuery, а именно функцию $.ajax(). Эта функция позволяет нам как передавать данные на сервер, так и получать ответы от сервера и все это в фоновом режиме, без перезагрузки страницы. Настройка приема или передачи данных зависит от параметров, с которыми вызывается функция $.ajax(). Основные из них будут рассмотрены ниже. Подробнее о параметрах можно прочесть в руководстве по jQuery.

Перейдем к рассмотрению примеров.

Важно!
Для того, чтобы примеры работали корректно, необходимо:
1. Все файлы должны быть записаны в кодировке UTF-8.
2. Скрипты должны выполняться на веб-сервере, а не запускаться в браузере, как файл.

Пример 1. Динамическое обновление контента по таймеру

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

Содержимое файла index.html.

function show() { $.ajax({ url: "time.php", cache: false, success: function(html){ $("#content").html(html); } }); } $(document).ready(function(){ show(); setInterval("show()",1000); });

В коде имеются несколько особенностей, поясним их.

1. Подключение библиотеки jQuery происходит в заголовке HTML файла, для этого записана данная строка.

Сам файл jquery.js - находится в той же папке, что и файлы примера.

2. В теле документа создается контейнер, в который мы будем загружать контент.

3. Странная, на первый взгляд, функция $(document).ready() требуется для корректной работы jQuery, к тому же в ней мы можем выполнить все приготовления к работе программы. В нашем случае мы вызываем функцию show(), в которой прописан механизм получения контента из другого файла, и настраиваем таймер, так, чтобы функция show() вызывалась один раз в секунду.

$(document).ready(function(){ show(); setInterval("show()",1000); });

4. Функция show() состоит из обращения к функции $.ajax() с определенным рядом параметров, которая позволяет нам в фоновом режиме получить информацию из внешнего файла на сервере.

$.ajax({ url: "time.php", cache: false, success: function(html){ $("#content").html(html); } });

Рассмотрим используемые параметры функции $.ajax().

Url: "time.php" Обращается к файлу time.php для получения контента. cache: false Результаты запросов не кэшируются. success: function(html){ $("#content").html(html); } При успешном выполнении запроса, управление переходит функции, которая получает контент в качестве параметра и записывает его контейнер. Запись в контейнер происходит вот в этой строке:
$("#content").html(html);

Содержимое файла time.php.

Смысл работы файла time.php - выводим текущее время на экран.

Скачать исходные файлы примера (16,6 кб):

Пример 2. Динамическое обновление контента по выбору пользователя

Программа, динамически загружающая контент, по выбору пользователя.

Содержимое файла index.html.

Какую страницу желаете открыть?

$(document).ready(function(){ $("#btn1").click(function(){ $.ajax({ url: "page1.html", cache: false, success: function(html){ $("#content").html(html); } }); }); $("#btn2").click(function(){ $.ajax({ url: "page2.html", cache: false, success: function(html){ $("#content").html(html); } }); }); });

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

Событие нажатия на кнопку "Страница 1" обрабатывается функцией $("#btn1").click(), а событие нажатия на кнопку "Страница 2" обрабатывается функцией $("#btn2").click().

Содержимое файлов page1.html и page2.html, которые загружаются в область контента динамически, представляет собой простые HTML-страницы или текстовые файлы с контентом.

Скачать исходные файлы примера (18,4 кб):

Пример 3. Отправка данных на сервер в фоновом режиме и получение контента

Рассмотрим пример, отправляющий введенное имя пользователя на сервер. Сервер при получении имени выдает приветствие и подсчитывает количество символов в введенном имени.

Содержимое файла index.html.

Введите имя:


$(document).ready(function(){ $("#myForm").submit(function(){ $.ajax({ type: "POST", url: "greetings.php", data: "username="+$("#username").val(), success: function(html){ $("#content").html(html); } }); return false; }); });

В теле документа создана форма для ввода имени пользователя. И контейнер для загрузки динамического контента.

Заметим, что сама форма не имеет привычных полей action и method. В качестве обработчика события нажатия на кнопку "Отправить", выступает функция $("#myForm").submit(). Рассмотрим эту функцию.

$("#myForm").submit(function(){ $.ajax({ type: "POST", url: "greetings.php", data: "username="+$("#username").val(), success: function(html){ $("#content").html(html); } }); return false; });

Как мы видим, основная работа опять связана с функцией $.ajax(). В этот раз появляются дополнительные параметры, не рассмотренные в примерах 1 и 2. А именно:

Type: "POST" Тип передачи данных. data: "username="+$("#username").val() Параметры, передаваемые серверу. В данном случае мы передаем содержимое поля username - имя пользователя. В общем случае, параметры записываются также, как в методе GET, одной строкой, например:
data: "username=Vasya&age=18&sex=male"

Обратим внимание, что в конце написана строка:

Return false; Это сделано для того, чтобы форма не пыталась передать данные файлу, из которого она запускается и не происходило перезагрузки страницы.

Содержимое файла greetings.php.

Выводим на экран приветствие и подсчитываем количество символов в имени.

Скачать исходные файлы примера (16,8 кб):

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

1. На страницах с динамическим обновлением контента, кнопка "Назад" в браузере не работает корректно.

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

3. Страницы с динамическим обновлением контента не индексируются поисковыми системами, т.к. они не выполняют команды JavaScript.

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

Урок, в котором на примерах рассмотрим создание простых асинхронных AJAX запросов к серверу. В качестве метода передачи запросов будем использовать как метод GET, так и метод POST. На сервере обработку запросов выполним с помощью скриптов PHP.

Что такое асинхронный запрос AJAX?

Технология AJAX в основном используется для создания асинхронных запросов к серверу. Асинхронный запрос - это такой запрос, который выполняется в фоновом режиме и не мешает пользователю взаимодействовать со страницей.

При отправке асинхронного запроса, браузер (страница) не "замораживается", т.е. с ней, как и прежде, можно работать. Но тогда как узнать, когда придёт ответ с сервера. Чтобы это определить, необходимо отслеживать свойство браузера readyState (состояние готовности). Данное свойство содержит число, по значению которого можно судить о том, в какой стадии находится запрос. В следующей таблице приведены основные значения свойства readyState и соответствующие им состояния.

Т.е. получается, что нам необходимо отследить, когда значение у свойства readyState будет равно 4. Это будет означать то, что на отправленный запрос, пришёл ответ с сервера. Остальные значения на практике используются довольно редко, и некоторые браузеры могут их не поддерживать.

Для того чтобы определить на какой стадии находится запрос, необходимо использовать событие объекта XMLHttpRequest onreadystatechange . Данное событие происходит каждый раз, когда изменяется значение свойства readyState . Следовательно, в обработчике этого события (неименованной или именованной функции) можно прописать действия, которые будут проверять равно ли данное свойство 4 и если равно, то например, вывести ответ сервера на страницу.

Создание асинхронного AJAX запроса (метод GET)

Рассмотрим создание асинхронного AJAX запроса на примере, который будет после загрузки страницы приветствовать пользователя и отображать его IP-адрес.

Для этого необходимо создать на сервере 2 файла в одном каталоге:

  • welcome.html – HTML-страница, которая будет отображаться пользователю. В этой же страницы поместим скрипт, который будет осуществлять все необходимые действия для работы AJAX на стороне клиента.
  • processing.php – PHP-файл, который будет обрабатывать запрос на стороне сервера, и формировать ответ. Начнём разработку с создания основной структуры файла welcome.html
  • Пример работы AJAX Пример работы AJAX // Здесь поместим код JavaScript, который будет отправлять запрос на сервер, получать его и обновлять содержимое страницы. Всё это будет работать без перезагрузки страницы

    Рассмотрим последовательность действий, которые необходимо выполнить на стороне клиента (в коде JavaScript):

    Подготовим данные, необходимые для выполнения запроса на сервере. Если для выполнения запроса на сервере данные никакие не нужны, то данный этап можно пропустить.

    Создадим переменную, которая будет содержать экземпляр объекта XHR (XMLHttpRequest).

    Настроим запрос с помощью метода open() .

    Указываются следующие параметры:

    • Метод, с помощью которого будет посылаться запрос на сервер (GET, POST).
    • URL-адрес, который будет обрабатывать запрос на сервере.
    • Тип запроса: синхронный (false) или асинхронный (true).
    • Имя и пароль при необходимости.
  • Подпишемся на событие onreadystatechange объекта XHR и укажем обработчик в виде анонимной или именованной функции. После этого создадим код внутри этой функции, который будет проверять состояние ответа, и выполнять определённые действия на странице. Ответ, который приходит с сервера, всегда находится в свойстве responseText .

    Дополнительно с проверкой значения свойства readyState числу 4, можно проверять и значение свойства status . Данное свойство определяет статус запроса. Если оно равно 200, то всё OK . А иначе произошла ошибка (например, 404 – URL не найден).

    Отправим запрос на сервер с помощью метода send() .

    Если используем для отправки запроса метод GET, то передавать данные в параметр данного метода не надо. Они передаются в составе URL.

    Если используем для отправки запроса метод POST, то данные необходимо передать в качестве параметра методу send() . Кроме этого, перед вызовом данного метода необходимо установить заголовок Content-Type, чтобы сервер знал в какой кодировке пришёл к нему запрос и смог его расшифровать.

    Содержимое элемента script:

    // 2. Создание переменной request var request = new XMLHttpRequest(); // 3. Настройка запроса request.open("GET","processing.php",true); // 4. Подписка на событие onreadystatechange и обработка его с помощью анонимной функции request.addEventListener("readystatechange", function() { // если состояния запроса 4 и статус запроса 200 (OK) if ((request.readyState==4) && (request.status==200)) { // например, выведем объект XHR в консоль браузера console.log(request); // и ответ (текст), пришедший с сервера в окне alert console.log(request.responseText); // получить элемент c id = welcome var welcome = document.getElementById("welcome"); // заменить содержимое элемента ответом, пришедшим с сервера welcome.innerHTML = request.responseText; } }); // 5. Отправка запроса на сервер request.send();

    В итоге файл welcome.html будет иметь следующий код:

    Пример работы AJAX Пример работы AJAX window.addEventListener("load",function() { var request = new XMLHttpRequest(); request.open("GET","processing.php",true); request.addEventListener("readystatechange", function() { if ((request.readyState==4) && (request.status==200)) { var welcome = document.getElementById("welcome"); welcome.innerHTML = request.responseText; } }); request.send(); });

    На сервере (с помощью php):

  • Получим данные. Если данные посланы через метод GET , то из глобального массива $_GET["имя"] . А если данные переданы с помощью метода POST , то из глобального массива $_POST["имя"] .
  • Используя эти данные, выполним некоторые действия на сервере. В результате которых получим некоторый ответ. Выведем его с помощью echo .
  • В приведенном выше коде мы получаем адрес студента с помощью порядкового номера и его имени.

    Для данного примера вам понадобится создать базу данных school и таблицу students . Таблица student содержит поля с именами, порядковым номером и адресом.

    Надеюсь, эта статья будет вам полезна.

    AJAX - это аббревиатура, которая означает Asynchronous Javascript and XML. На самом деле, AJAX не является новой технологией, так как и Javascript, и XML существуют уже довольно продолжительное время, а AJAX - это синтез обозначенных технологий. AJAX чаще всего ассоцириуется с термином Web 2.0 и преподносится как новейшее Web-приложение.

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

    Обобщим достоинства AJAX:

    • Возможность создания удобного Web-интерфейса
    • Активное взаимодействие с пользователем
    • Удобство использования
    AJAX использует два метода работы с веб-страницей: изменение Web-страницы не перезагружая её, и динамическое обращение к серверу. Второе может осуществляться несколькими способами, в частности, XMLHttpRequest, о чем мы и будем говорить, и использование техники скрытого фрейма.Обмен данными

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

    Обмениваться данными с сервером можно двумя способами. Первый способ - это GET-запрос. В этом запросе вы обращаетесь к документу на сервере, передавая ему аргументы через сам URL. При этом на стороне клиента будет логично использовать функция Javascript`а escape для того, чтобы некоторые данные не прервали запрос.

    Клиент часть, написанная на Javascript, должна обеспечивать необходимую функциональность для безопасного обмена с сервером и предоставлять методы для обмена данными любым из вышеперечисленных способов. Серверная часть должна обрабатывать входные данные, и на основе их генерировать новую информацию (например, работая с базой данных), и отдавать ее обратно клиенту. Например, для запроса информации с сервера можно использовать обычный GET-запрос с передачей нескольких и небольших по размеру параметров, а для обновления информации, или добавления новой информации потребуется использовать уже POST-запрос, так как он позволяет передавать большие объемы данных.

    Как уже было сказано, AJAX использует асинхронную передачу данных. Это значит, что пока идёт передача данных, пользователь может совершать другие, необходимые ему действия. В это время следует оповестить пользователя о том, что идёт какой-либо обмен данными, иначе пользователь подумает, что произошло что-то не то и может покинуть сайт, или повторно вызвать «зависшую», по его мнению, функцию. Индикация во время обмена данными в приложении Web 2.0 играет очень важную роль: посетители могли еще не привыкнуть к таким способам обновления страницы.

    Ответ от сервера может быть не только XML, как следует из названия технологии. Помимо XML, можно получить ответ в виде обычного текста, или же JSON (Javascript Object Notation). Если ответ был получен простым текстом, то его можно сразу вывести в контейнер на странице. При получении ответа в виде XML, обычно происходит обработка полученного XML документа на стороне клиента и преобразование данных к (X)HTML. При получении ответа в формате JSON клиент должен лишь выполнить полученный код (функция Javascript`а eval) для получения полноценного объекта Javascript. Но здесь нужно быть осторожным и учитывать тот факт, что с использованием этой технологии может быть передан вредоносный код, поэтому перед выполнением полученного с сервера кода следует его тщательно проверить и обработать. Существует такая практика, как «холостой» запрос, при котором никакой ответ от сервера не приходит, лишь изменяются данные на стороне сервера.

    В разных браузерах данный объект обладает разными свойствами, но в целом он совпадает.

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

    Заметьте, что названия методов записаны в том же стиле (Camel-style), что и другие функции Javascript. Будьте внимательны при их использовании.

    abort() - отмена текущего запроса к серверу.

    getAllResponseHeaders() - получить все заголовки ответа от сервера.

    getResponseHeader(«имя_заголовка») - получить указаный заголовок.

    open(«тип_запроса»,«URL»,«асинхронный»,«имя_пользователя»,«пароль») - инициализация запроса к серверу, указание метода запроса. Тип запроса и URL - обязательные параметры. Третий аргумент - булево значение. Обычно всегда указывается true или не указывается вообще (по умолчанию - true). Четвертый и пятый аргументы используются для аутентификации (это очень небезопасно, хранить данные об аутентификации в скрипте, так как скрипт может посмотреть любой пользователь).

    send(«содержимое») - послать HTTP запрос на сервер и получить ответ.

    setRequestHeader(«имя_заголовка»,«значение») - установить значения заголовка запроса.

    Свойства объекта XMLHttpRequest

    onreadystatechange - одно из самых главных свойств объекта XMLHttpRequest. С помощью этого свойства задаётся обработчик, который вызывается всякий раз при смене статуса объекта.

    readyState - число, обозначающее статус объекта.

    responseText - представление ответа сервера в виде обычного текста (строки).

    responseXML - объект документа, совместимый с DOM, полученного от сервера.

    status - состояние ответа от сервера.

    statusText - текстовое представление состояния ответа от сервера.

    Следует подробнее расммотреть свойство readyState:

    • 0 - Объект не инициализирован.
    • 1 - Объект загружает данные.
    • 2 - Объект загрузил свои данные.
    • 3 - Объек не полностью загружен, но может взаимодействовать с пользователем.
    • 4 - Объект полностью инициализирован; получен ответ от сервера.
    Именно опираясь на состояние готовности объекта можно представить посетителю информацию о том, на какой стадии находится процесс обмена данными с сервером и, возможно, оповестить его об этом визуально.Создание объекта XMLHttpRequest

    Как уже говорилось выше, создание данного объекта для каждого типа браузера - уникальный процесс.

    Например, для создания объекта в Gecko-совместимых браузерах, Konqueror`е и Safari, нужно использовать следующее выражение:

    Var Request = new XMLHttpRequest();

    А для Internet Explorer`а используется следующее:

    Var Request = new ActiveXObject("Microsoft.XMLHTTP");

    Var Request = new ActiveXObject("Msxml2.XMLHTTP");

    Теперь, чтобы добиться кроссбраузерности, необходимо сложить все функции в одну:

    Function CreateRequest() { var Request = false; if (window.XMLHttpRequest) { //Gecko-совместимые браузеры, Safari, Konqueror Request = new XMLHttpRequest(); } else if (window.ActiveXObject) { //Internet explorer try { Request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (CatchException) { Request = new ActiveXObject("Msxml2.XMLHTTP"); } } if (!Request) { alert("Невозможно создать XMLHttpRequest"); } return Request; }

    После всего этого можно создавать данный объект и не беспокоится за работоспособность на популярных браузерах. Но создать объект можно в разных местах. Если создать его глобально, то в определенный момент времени возможен будет только один запрос к серверу. Можно создавать объект всякий раз, как происходит запрос к серверу (это почти полностью решит проблему).

    Запрос к серверу

    Алгоритм запроса к серверу выглядит так:

    • Проверка существования XMLHttpRequest.
    • Инициализация соединения с сервером.
    • Посылка запрса серверу.
    • Обработка полученных данных.
    Для создания запроса к серверу мы создадим небольшую функцию, которая будет по функциональности объединять в себе функции для GET и POST запросов.

    /* Функция посылки запроса к файлу на сервере r_method - тип запроса: GET или POST r_path - путь к файлу r_args - аргументы вида a=1&b=2&c=3... r_handler - функция-обработчик ответа от сервера */ function SendRequest(r_method, r_path, r_args, r_handler) { //Создаём запрос var Request = CreateRequest(); //Проверяем существование запроса еще раз if (!Request) { return; } //Назначаем пользовательский обработчик Request.onreadystatechange = function() { //Если обмен данными завершен if (Request.readyState == 4) { //Передаем управление обработчику пользователя r_handler(Request); } } //Проверяем, если требуется сделать GET-запрос if (r_method.toLowerCase() == "get" && r_args.length > 0) r_path += "?" + r_args; //Инициализируем соединение Request.open(r_method, r_path, true); if (r_method.toLowerCase() == "post") { //Если это POST-запрос //Устанавливаем заголовок Request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8"); //Посылаем запрос Request.send(r_args); } else { //Если это GET-запрос //Посылаем нуль-запрос Request.send(null); } }

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

    Function ReadFile(filename, container) { //Создаем функцию обработчик var Handler = function(Request) { document.getElementById(container).innerHTML = Request.responseText; } //Отправляем запрос SendRequest("GET",filename,"",Handler); }

    Именно таким образом происходит взаимодействие с сервером.

    Обработка ответа

    В предыдущем примере мы сделали функцию запроса к серверу. Но она, по сути, небезопасна, так как мы не обрабатываем состояния объекта и состояния ответа от сервера.

    Дополним наш код, чтобы он смог выводить визуальное оповещение о процессе загрузки.

    Request.onreadystatechange = function() { //Если обмен данными завершен if (Request.readyState == 4) { //Передаем управление обработчику пользователя r_handler(Request); } else { //Оповещаем пользователя о загрузке } } ...

    Как вы уже знаете, объект XMLHttpRequest позволяет узнать статус ответа от сервера. Воспользуемся этой возможностью.

    Request.onreadystatechange = function() { //Если обмен данными завершен if (Request.readyState == 4) { if (Request.status == 200) { //Передаем управление обработчику пользователя r_handler(Request); } else { //Оповещаем пользователя о произошедшей ошибке } } else { //Оповещаем пользователя о загрузке } } ...

    Варианты ответа от сервера

    От сервера можно получить данные нескольких видов:

    • Обычный текст
    Если вы получаете обычный текст, то вы можете сразу же направить его в контейнер, то есть на вывод. При получении данных в виде XML вы должны обработать данные с помощью DOM-функций, и представить результат с помощью HTML.

    JSON - это объектная нотация Javascript. С ее помощью можно представить объект в виде строки (здесь можно привести аналогию с функцией сериализации). При получении JSON-данных вы должны выполнить их, чтобы получить полноценный объект Javascript и произвести с ним необходимые операции. Помните, что такая передача данных и выполнение их не являются безопасными. Вы должны следить за тем, что поступает на исполнение.

    Пример кода JSON:
    { "data": { "misc": [ { "name" : "JSON-элемент один", "type" : "Подзаголовок 1" }, { "name" : "JSON-элемент два", "type" : "Подзаголовок 2" } ] } }

    При получении такого кода, производим следующее действие:

    Var responsedata = eval("(" + Request.responseText + ")")

    После выполнения данного кода вам будет доступен объект responsedata .

    Работа с серверными языками программирования

    Такая работа ничем не отличается от обычной. Для примеров я возьму PHP в качестве серверного языка. В клиентской части ничего не изменилось, но серверная часть теперь представлена PHP-файлом.

    По традиции, начнем с приветствия нашему замечательному миру:

    Echo "Hello, World!";

    При обращении к этому файлу клиенту вернется строка Hello, World. Как вы понимаете, это представляет широчайшие возможности для построения приложений. На основе передачи аргументов при вызове сервера с помощью XMLHttpRequest можно сделать параметризацию вывода, тем самым обеспечив обширную функциональность Web-приложения.

    Помимо PHP, можно использовать любой другой серверный язык программирования.