» » Як написати AJAX-додаток

Як написати AJAX-додаток

Як написати AJAX-додаток
Це два-три роки тому AJAX був у дивину (та й самого слова AJAX тоді ще не вигадали). Тепер веб-додатки, сторінки яких обновляються "на льоту", у порядку речей. Навіть навпаки, без AJAX важко й уявити собі деякі сервіси.
Як працювали звичайні веб-додатки? Як правило, на подію (клич по посиланню або натискання на кнопку) браузер реагував відправленням запиту серверу. Коли із сервера приходила відповідь, весь вміст сторінки повністю оновлювалося.

Одна з проблем полягала в тому, що при оновленні вмісту сторінки веб-додаток переходить в новий стан. З інформації про попередній стані зберігаються лише дані, передані в запиті. Чим більш точна інформація про колишньому стані системи потрібно, тим більше даних необхідно пересилати в запиті.
Іншим недоліком є необхідність пересилати повторювані масиви даних клієнтові після кожної події. Наприклад, якщо користувач помилився при заповненні форми, то замість короткого повідомлення про помилку доводиться знову завантажувати і форму, і всю введену раніше інформації.
Сучасні браузери, які підтримують стандарти W3C DOM, дозволяють вивести веб-додаток на новий рівень.
Схема взаємодії залишається майже такою ж. Ось тільки відправляє запит і отримує відповідь з сервера тепер скрипт на стороні клієнта, а замість оновлення всієї сторінки – оновлюється тільки її частину (Замість оновлення можуть вживатися інші дії, наприклад, відправлятися наступний запит).
Веб-додаток виходить розподіленим, і частина логіки знаходиться на стороні клієнта, а частина – на стороні сервера. Такі програми та називають терміном "AJAX Applications" (абревіатура розшифровується як Asynchronous javascript And Xml Applications).
Об'єкт XMLHTTPRequest
Для асинхронних запитів від клієнта до сервера на стороні браузера служить спеціальний об'єкт під назвою XMLHTTPRequest.
Перерахуємо методи і властивості об'єкта, які будуть використані далі:
XMLHTTPRequest.open ("method", "URL", async, "uname", "pswd") – створює запит до сервера.
method – тип запиту, наприклад, GET
URL – URL запиту, наприклад http://localhost/file.xml
async – якщо True, то буде використовуватися асинхронний запит, тобто виконання скрипта продовжиться після відправлення запиту. В іншому випадку скрипт буде чекати відповіді від сервера, заморозивши UI.
uname, pswd – логін та пароль для простої веб-авторизації.
XMLHTTPRequest.send ("content")
– відправляє запит на сервер. Значенням content можуть бути дані для POST-запиту або порожній рядок.
XMLHTTPRequest.onreadystatechange – обробник подій спрацьовує на кожну зміну стану об'єкта. Стану об'єкта можуть бути наступними:
0 – до того як запит відправлений (uninitialized)
1 – об'єкт инициализирован (loading)
2 – отримана відповідь від сервера (loaded)
3 – з'єднання з сервером активно (interactive)
4 – об'єкт завершив роботу (complete)
XMLHTTPRequest.responseText – повертає отримані від сервера дані у вигляді рядка.
XMLHTTPRequest.responseXML – якщо відповідь сервера прийшла у вигляді правильного XML, повертає XML DOM об'єкт.
XMLHTTPRequest.status – повертає статус HTTP-відповіді у вигляді числа. Наприклад, 404 якщо запитувана сторінка не була знайдена на сервері.
Розглянемо застосування об'єкта на прикладі простого AJAX-додатки.

Поле SELECT з пошуком
Припустимо в нас є таблиця, в якій близько мільйона записів. Користувачеві необхідно вибрати всього один запис з таблиці (реалізація відносини "один до багатьох"). Вибір користувача є всього лише одним з етапів заповнення великий веб-форми.
Природно, для того, щоб користувач міг вибрати потрібний запис з мільйона, потрібні якісь кошти пошуку цієї самої запису. Наприклад, простий текстовий пошук по найменуванню.
У традиційному веб-додатку для цієї мети довелося б використовувати окрему сторінку і зберігати інші дані форми в сесії користувача, або розбивати процес заповнення форми на декілька етапів. У AJAX-додатку додаткова сторінка не потрібна.
Вибір запису буде реалізований з допомогою двох елементів веб-форми. Перший елемент – це текстове поле, де користувач вводить ключове слово. Воно відсилається на сервер, а той повертає лише ті рядки з таблиці, які задовольняють умові пошуку. Відповідь сервера (у вигляді списку) міститься в полі SELECT, в якому користувач і зробить остаточний вибір. Таким чином, при відправленні всієї форми на сервер потрапить вибраного в полі SELECT значення у вигляді ID записи з великої таблиці.
У HTML виглядати це може так:
<input type="text" ="" />	
<select id="id_select" name="id_select">
<option selected="selected" value=""></option>
</select>

На будь-яку подію KeyUp (отжатие кнопки) у текстовому полі викликається функція lookup ("текст", "id-selecta", "url")
function lookup(text, select_id, url) {
// Отримуємо об'єкт XMLHTTPRequest
        if(!this.http){
            this.http = get_http();
            this.working = false;
        }
// Запит
        if (!this.working && this.http) {
            var http = this.http;
// Якщо в текстовому полі менше трьох
// Символів - не робимо нічого
           if (text.length <3 ) return;
// Додаємо закодований текст
// В URL запиту
            url = url + "?text="+encodeURIComponent(text);
// Створюємо запит
            this.http.open("GET", url, true);
// Прикріплюємо до запиту функцію-обробник
// Подій
            this.http.onreadystatechange = function() {
// 4 - дані готові для обробки
                if (http.readyState == 4) {
                    fill(select_id, http.responseText);
                    this.working = false;
                  }else{
// Дані в процесі отримання, 
// Можна повеселити користувача
// Повідомленнями 
// ЧЕКАЙТЕ ВІДПОВІДІ
                  }
            }
            this.working = true;
            this.http.send(null);
        }
        if(!this.http){
alert ("Помилка при створенні XMLHTTP об'єкта!")
        }
    }

Як видно, на початку ми отримуємо XMLHTTP-об'єкт за допомогою функції get_http (). Потім пошуковий текст кодується в стилі URL і формується GET-запит до сервера. URL запиту в даному випадку буде виглядати приблизно так: http://localhost/cgi-bin/xmlhttp.cgi?text =…
Скрипт на сервері, отримавши значення text, робить пошук в таблиці і відсилає результат клієнтові. У обробнику подій об'єкта XMLHTTP, коли дані від сервера отримані і готові до використання, викликається функція fill ("select_id", "data"), яка заповнить список SELECT отриманими даними.
Функція get_http () – це крос-браузерна реалізація отримання об'єкта XMLHTTP (у кожному браузері він виходить по-своєму). Її реалізацію з коментарями ви можете легко знайти в інтернеті, це, так би мовити, приклад з підручника.
function get_http(){
    var xmlhttp;
    /*@cc_on
    @if (@_jscript_version >= 5)
        try {
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                xmlhttp = new 
                ActiveXObject("Microsoft.XMLHTTP");
            } catch (E) {
                xmlhttp = false;
            }
        }
    @else
        xmlhttp = false;
    @end @*/
if (! xmlhttp & & typeof XMLHttpRequest! = "undefined") {
        try {
            xmlhttp = new XMLHttpRequest();
        } catch (e) {
            xmlhttp = false;
        }
    }
    return xmlhttp;
}

Функція fill () отримує на вхід значення параметра ID списку SELECT, який необхідно заповнити, і самі дані, отримані з сервера.
Для простоти припустимо, що дані з сервера ми отримуємо у вигляді таблиці, поля якої розділені символом табуляції "t", а рядки – символом перенесення рядка "n":
id1 t name1 n
id2 t name2 n
...

На підставі змісту цієї таблиці ми будемо заповнювати поле SELECT елементами OPTION.
function fill (select_id, data){
// Поле SELECT в змінну у вигляді об'єкта
    var select = document.getElementById(select_id);
// Очищаємо SELECT
    select.options.length = 0;
// Якщо даних немає - не робимо більше нічого
    if(data.length == 0) return;
// У масиві arr - рядки отриманої таблиці
    var arr = data.split("n");
// Для кожного рядка
    for(var i in arr){
// У масиві val - поля отриманої таблиці
        val = arr[i].split("t");
// Додаємо новий об'єкт OPTION до нашого SELECT
        select.options[select.options.length]=
        new Option(val[1], val[0], false, false);
    }
}

Готово. Тепер для будь-якої веб-форми програми ми можемо реалізувати подібний вибір значення з багатомільйонного списку, який для користувача буде виглядати як лічені натиснення клавіш. У локальній мережі вибір відбувається практично миттєво. У випадку нестабільного або низької з'єднання з сервером, необхідно також оповіщати користувача про те, що завантаження даних з сервера ще не завершена. Корисно передбачити і засоби для реакції на обрив з'єднання.


928 09.10.13



Напівжирний Нахилений текст Підкреслений текст Перекреслений текст | Вирівнювання по лівому краю По центру Вирівнювання по правому краю | Вставка смайликів Вибір кольору | Прихований текст Вставка цитати Перетворити вибраний текст з транслітерації в кирилицю Вставка спойлеру