→ Пошук по сайту       Увійти / Зареєструватися
Знання Технологія AJAX

Формати відповіді сервера в Ajax. Розробка Ajax-фреймворку

Компетенція Використання AJAX

Вступ

З метою спрощення роботи з Ajax слід розробити бібліотеку (JavaScript-PHP), з метою реалізації прозорого використання асинхронних звернень до сервера. 

1.Формати відповіді для XMLHttpRequest

XMLHttpRequest може приймати відповідь у двох форматах – як простий текст і як XML. Для цього використовуються відповідні властивості об’єкта:

responseText

текст відповіді на запит

responseXML

текст відповіді на запит в вигляді XML, котрий по тому може бути розібраний методами DOM

На практиці у якості відповіді сервера можна використати наступні формати:

  • Простий текст (через responseText)
  • Форматований HTML-текст (через responseText)
  • JSON(через responseText)
  • JavaScript-код (через responseText)
  • XML(через responseXML)

Відповідь у форматі JSON

JSON– (англ. JavaScript Object Notation, вимовляється джейсон) — нотація опису об’єктів в JavaScript. Це текстовий формат обміну даними заснований на JavaScript. JSON базується на тексті, і може бути з легкістю прочитаним людиною. Формат дозволяє описувати об'єкти та інші структури даних. Цей формат головним чином використовується для передачі структурованої інформації через мережу (для процесу, що називають серіалізацією).

JSONє синтаксично правильним фрагментом коду JavaScript. Тому обробляється він як правило за допомогою ф-ії eval(), яка призначена для виконання JavaScript-коду, який міститься в рядку.

JSONзнайшов своє головне призначення у написанні веб-програм, а саме при використанні технології Ajax. JSON виступає як заміна XML під час асинхронної передачі структурованої інформації між клієнтом та сервером. При цьому перевагою JSON перед XML є те, що він займає менше місця і прямо інтерпретується за допомогою JavaScript в об'єкти.

Синтаксис JSON

JSONбудується на двох структурах:

  • Набір пар ім'я/значення. У різних мовах це реалізовано як об'єкт, запис, структура, словник, хеш-таблиця, список з ключем або асоціативним масивом.
  • Впорядкований список значень. У багатьох мовах це реалізовано як масив, вектор, список, або послідовність.

Це універсальні структури даних. Теоретично всі сучасні мови програмування підтримують їх в одній або іншій формі. Оскільки JSON використовується для обміну даними між різними мовами програмування, то має сенс будувати його на цих структурах.

У JSON використовуються їх наступні форми:

  • Об'єкт— це невпорядкована множина пар ім'я/значення. Об'єкт починається з символу { і закінчується символом }. Кожне значення слідує за : і пари ім'я/значення відділяються комами.
  • Масив— це впорядкована множина значень. Масив починається символом [ і закінчується символом ]. Значення відділяються комами.
  • Значенняможе бути рядком в подвійних лапках, або числом, або логічними true чи false, або null, або об'єктом, або масивом. Ці структури можуть бути вкладені одна в одну.
  • Рядок— це впорядкована множина з нуля або більше символів юнікода, обмежена подвійними лапками, з використанням escape-послідовностей, що починаються із зворотної косої риски (backslash). Символи представляються простим рядком.

Тип String дуже схожий на String в мовах C і Java. Число теж дуже схоже на C- або Java-число, за винятком того, що вісімкові та шістнадцяткові формати не використовуються. Пропуски можуть бути вставлені між будь-якими двома лексемами.

Наступний приклад демонструє подання JSON-об'єкту, що описує людину. У об'єкті є рядкові поля імені і прізвища, об'єкт, що описує адресу, і масив, що містить список телефонів.

 {

"firstName": "Іван",

   "lastName": "Коваленко",

   "address": {

       "streetAddress": "вул. Грушевського 14, кв.101",

       "city": "Київ",

       "postalCode": 21000

   },

   "phoneNumbers": [

       "044 123-1234",

       "050 123-4567"

   ]

}

На мові XML подібна структура мала б такий вигляд:

 <person>

  <firstName>Іван</firstName>

  <lastName>Коваленко</lastName>

  <address>

    <streetAddress>вул. Грушевського 14, кв.101</streetAddress>

    <city>Київ</city>

    <postalCode>21000</postalCode>

  </address>

  <phoneNumbers>

    <phoneNumber>044 123-1234</phoneNumber>

    <phoneNumber>050 123-4567</phoneNumber>

  </phoneNumbers>

</person>
 

Використання JSON в AJAX

Наступний фрагмент коду JavaScript показує, як клієнт може використати XMLHttpRequest для запиту об'єктів в форматі JSON з серверу.

  // ініціалізація XMLHttpRequest

...

xhr.onreadystatechange=function(){

    if (xhr.readyState==4 && xhr.status==200){

        obj=eval('( '+xhr.responseText+')');

        alert ('Hello '+obj.name+' ' +obj.lastname);

    }

}

Відповідь сервера:

 echo '{"name":"Petro", "lastname":"Ivanenko"}';

Результат обробки запита:

Зауваження

Використання запиту XMLHttpRequest обмежено правилом одного домену (same origin policy): URL, що відповідає на запит, має посилатися на той же DNS домен, що обслуговує сторінку, яка  ініціювала запит.

Динамічний тег <script> також можна використати для підвантаження JSON-даних. Ця техніка можлива, щоб обійти надто правило одного домену, але вона не є безпечною.

Питання безпеки

Хоча JSON призначений для передачі даних в серіалізованому вигляді, його синтаксис відповідає синтаксису JavaScript і це створює низку проблем безпеки. Часто для обробки даних, отриманих від зовнішнього джерела у форматі JSON, до них застосовується функція eval()без якої-небудь попередньої перевірки.

У разі, якщо замість опису об’єкта в тексті міститься деякий JavaScript-код, ф-ія eval() забезпечить його виконання.

Відповідь у вигляді JavaScript-коду

Аналогічно JSON, у випадку, коли сервер надсилає JavaScript-код, його можна обробити на клієнті за допомогою ф-ії eval():

Клієнт:

 <script language="javascript">

xhr=new XMLHttpRequest();

xhr.onreadystatechange=function(){

    if (xhr.readyState==4 && xhr.status==200){

        eval(xhr.responseText);

     }

}

function doReq(){

    xhr.open('get','ajax.php',true);

    xhr.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");

    xhr.send(null);  

}

</script>

<body>

<button onclick="doReq();">go</button>

<div id="userName"></div>

</body> 

Сервер:

 $userName='Petro Ivanenko';

echo"document.getElementById('userName').innerHTML='$userName';";

Відповідь у форматі XML

Розширювана мова розмітки(англ. Extensible Markup Language, скорочено XML) — запропонований консорціумом World Wide Web (W3C) стандарт побудови мов розмітки ієрархічно структурованих даних для обміну між різними застосунками, зокрема, через Інтернет. XML документ складається із текстових знаків, і придатний до читання людиною.

У випадку використання XML-відповіді серевера в Ajax, доступ до XML-відповіді відбувається за допомогою властивості XMLHttpRequest responseXML. Після чого отриманий XML необхідно обробити засобами DOM.

Приклад використання XML в AJAX

Код клієнта:

 functionloadXMLDoc(url)

{

if (window.XMLHttpRequest)

  {// code for IE7+, Firefox, Chrome, Opera, Safari

  xmlhttp=new XMLHttpRequest();

  }

else

  {// code for IE6, IE5

  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

  }

xmlhttp.onreadystatechange=function()

  {

  if (xmlhttp.readyState==4 && xmlhttp.status==200)

    {

    txt="<table border='1'><tr><th>Title</th><th>Artist</th></tr>";

    x=xmlhttp.responseXML.documentElement.getElementsByTagName("CD");

    for (i=0;i<x.length;i++)

      {

      txt=txt + "<tr>";

      xx=x[i].getElementsByTagName("TITLE");

        {

        try

          {

          txt=txt + "<td>" + xx[0].firstChild.nodeValue+ "</td>";

          }

        catch (er)

          {

          txt=txt + "<td>&nbsp;</td>";

          }

        }

    xx=x[i].getElementsByTagName("ARTIST");

      {

        try

          {

          txt=txt + "<td>" + xx[0].firstChild.nodeValue+ "</td>";

          }

        catch (er)

          {

          txt=txt + "<td>&nbsp;</td>";

          }

        }

      txt=txt + "</tr>";

      }

    txt=txt + "</table>";

    document.getElementById('txtCDInfo').innerHTML=txt;

    }

  }

xmlhttp.open("GET",url,true);

xmlhttp.send();

}

XML-відповідь сервера:

 <?xml version="1.0" encoding="UTF-8"?>

<CATALOG>

     <CD>

           <TITLE>Empire Burlesque</TITLE>

           <ARTIST>Bob Dylan</ARTIST>

           <COUNTRY>USA</COUNTRY>

           <COMPANY>Columbia</COMPANY>

           <PRICE>10.90</PRICE>

           <YEAR>1985</YEAR>

     </CD>

     <CD>

           <TITLE>Greatest Hits</TITLE>

           <ARTIST>Dolly Parton</ARTIST>

           <COUNTRY>USA</COUNTRY>

           <COMPANY>RCA</COMPANY>

           <PRICE>9.90</PRICE>

           <YEAR>1982</YEAR>

     </CD>

     <CD>

           <TITLE>Still got the blues</TITLE>

           <ARTIST>Gary Moore</ARTIST>

           <COUNTRY>UK</COUNTRY>

           <COMPANY>Virgin records</COMPANY>

           <PRICE>10.20</PRICE>

           <YEAR>1990</YEAR>

     </CD>

    

</CATALOG>
 

2.Оптимізація використання Ajax і розробка власних Ajax-фреймворків

Оптимізація запуску запиту

Можна використати об’єкт-надбудову над XMLHttpRequest. Міститиме такі члени:

  • Створення XMLHttpRequest (спрацьовує автоматично в конструкторі)
  • Метод, що спрацьовує в момент, коли відповідь готова.
  • Експрес-функція створення запиту

На крайній випадок замість об’єкту можна створити бібліотеку функцій, які повторюють відповідний функціонал.

Гіпотетичний приклад використання такого об’єкта може мати вигляд:

 ajax=new MyAjax();

var params={'name':'Petro','surname':'Ivanenko'};

function callbackFunc(theAjax){

    document.getElementById('userName').innerHTML=theAjax.response;

}

ajax.run('post','myscript.php',params, callbackFunc);

Або:  

 ajax=new MyAjax();

var params={'name':'Petro','surname':'Ivanenko'};

ajax.callback=function (theAjax){

    document.getElementById('userName').innerHTML=theAjax.response;

}

ajax.run('post','myscript.php',params);

 

Ajax-PHPфреймворк на основі відповіді у вигляді JavaScript

Передумови

У випадку застосунку без Ajax архітектура веб-застосунку має наступний вигляд:

  • Сервер [PHP]отримує синхронні запити від браузера, доступається до БД і генерує інтерфейс клієнта [HTML, JavaScript]
  • БД[MySQL]

Зауваження

У даному випадку розглядається архітектура обміну даними і формування інтерфейсу. Загальна  клієнт-серверна архітектура на основі протоколу HTTP в даному випадку не є безпосереднім предметом обговорення.

Існує багато методик, за якими пропонується використовувати Ajax таким чином, що це ускладнює проект до рівня три-ланкового застосунку (трехзвенного приложения):

  • Клієнт [HTML, JavaScript](інтерфейс, проста бізнес-логіка) – нічого не знає про БД і бізнес-логіку
  • Сервер застосунків [PHP] (доступ до БД, бізнес-логіка, постачання даних клієнту) – нічого не знає про інтерфейс клієнта
  • БД[MySQL]

Штучне архітектурне ускладнення тут полягає у тому, що проміжна ланка (сервер [PHP]) насправді не тільки «знає» про інтерфейс клієнта, а й формує його. Тому актуальним є розробка такого фреймворку, що додасть інтерактивності інтерфейсу клієнта і дозволить прозоро обробляти події на сервері, відразу формуючи зміни в клієнтському інтерфейсі.

Подібна прозорість дозволяє спростити архітектуру до рівня обробки подій в десктопному (настільному) застосунку.

Архітектура

Елементарна ідея полягає в налаштуванні клієнт-серверного Ajax-«каналу», де клієнт надсилає ім’я і параметри події, а сервер відповідає готовим JavaScript-кодом, який обробляється на клієнті єдиною функцією:

Інструментарій

PHPдозволяє виконувати функції за допомогою змінних, що містять ім’я функції:

 function myFunc($n){

     return $n*$n;

}

$myVar=”myFunc”;

$param=5;

$myVar($param);
 

Цю властивість зручно використати при створенні диспетчера подій для обробки потоку Ajax-запитів клієнта:

 // отримати інформацію про подію

$event=$_REQUEST[‘ajaxEvent’];

$params=$_REQUEST[‘params’];

// сформувати ім’я обробника

$handler=’ajax_’.$event;

// запустити обробник події і надіслати відповідь клієнту

if (function_exists($handler){

echo $handler($params);

}else echo ‘unknown event’;

 // обробники подій

functionajax_getName($params){

     var $str=‘HelloMister’.$params[0].’ ’. $params[2].’!’;

     return “document.getElementById(‘userName’).innerHTML=’$str’;”;

}
 

Тут передбачається, що параметри від клієнта передано у вигляді одномірного масива, наприклад так (URL): 

 ?ajaxEvent=getName&params[]=Petro&params[]=Ivanenko

На клієнті кожна реакція  сервера на Ajax-подію обробляється за допомогою ф-ії eval(). Зручність написання JavaScript-коду на стороні сервера зумовлена можливістю маніпулювати змінними PHP і результатами SQL-запитів безпосередньо при підготовці клієнтського коду.

Висновок

Перевагою усього підходу є можливість під час обробки події клієнта звести до єдиної «області видимості» клієнтський інтерфейс, бізнес-логіку і роботу з БД, не знижуючи при цьому рівень безпеки. 

Підхід підходить для одно-доменної веб-системи (порталу), і при розумному структуруванні та використанні ООП програмний код матиме необхідну модульність і простоту. 

© Титенко С.В. З конспекту лекцій. НТУУ "КПІ". Кафедра АПЕПС.

загрузка...
Сторінки, близькі за змістом