Ajax - примеры. Ajax скрипты
Интернет обеспечивает посетителю видимость каждого ресурса, находящегося на хостинге в сети, а браузеру - доступ через сетевые протоколы, механизмы вызова отдельных скриптов, передачу/получение информации. Совокупность страниц, составляющих сайт, имеет общий root - уникальную ссылку (доменное имя, уникальный адрес узла).
Неважно, ресурс реагирует на посещение статично или создает ответ динамически. Даже если вид и содержание страницы зависят от каких-либо условий, неделимой единицей общения сервера и клиента (браузера) является законченный HTML-документ с кодом, картинками, таблицами стилей, файлами и другим необходимым содержанием и окружением. Если что-то здесь не так, браузер отобразит все что «сумел» получить, разобрать и исполнить.
Многие перспективные технологии появились очень давно, но были незаслуженно забыты или не использовались должным образом. Первые AJAX (примеры использования объекта XMLHttpRequest) появились много лет назад, но успех и известность пришли гораздо позже.
Все сразу или только то, что нужно
В классическом варианте сайт - имя, IP-адрес и ссылка (все это синонимы, обозначающие одну и ту же точку в интернет-пространстве). То, что за этим лежит главная страница сайта - додумал по собственной инициативе современный "разработчик", который даже не задался вопросом: почему именно так? Почему сайт есть главная страница, с которой можно попасть на любую другую? Такой вариант - явно не идеал, это конкретное содержание и фактический функционал.
Проще говоря, если человеку нужно к стоматологу, он идет по нужному адресу с конкретной целью, а не на кухню за хирургическим вмешательством и не в библиотеку за консультацией терапевта. В месте, где этот кто-то оказался, он увидит, но не получит стоматологическую поликлинику в полном объеме. Максимум, на что может рассчитывать посетитель - регистратура и направление (точный путь) к врачу. Причем на месте (по прибытии) может измениться как врач, так и место назначения.
Но вот сайт обычно всегда грузится в полном боекомплекте, ничто не меняется по факту загрузки, с учетом времени того, кто пришел... А ведь даже в случае, когда он есть ресурс реальной поликлиники, то при первом посещении нового клиента достаточно дать страницу информации, контактов и окошко регистратуры... Можно предусмотреть, что визит на сайт был нанесен в нерабочее время, а назначенный врач отсутствует, прием временно производится в ином кабинете...
Точка в интернет-пространстве
Классическая реакция ресурса интернет-пространства - в ответ на запрос выдать страницу сайта (обычно главную), а потом другие, по желанию посетителя. Сервер сайта содержит также картинки, стили, коды скриптов JavaScript, PHP и пр. Далеко не все PHP-файлы делают страницы, некоторые из них могут реагировать на AJAX запросы: принимать, обрабатывать и отправлять информацию.
Написать скрипт несложно. Но, получая управление на точке в интернет-пространстве, нельзя определить, кто и по какому поводу обратился, то есть активировал это имя, IP-адрес и ссылку. Любое движение по сети происходит программно, в основном через браузер, но также через роботов различного происхождения и назначения, посредством действий других сайтов.
Скрипт, получивший управление, может точно знать только: время посещения, через какой браузер зашел посетитель, с какой ссылки, с какого IP-адреса и наличие cookies. Только последнее может дать информацию, как сформировать главную страницу, но только в том случае, если этот посетитель уже был здесь . Во всех остальных ситуациях возможно генерировать только общий ответ сервера. AJAX-примеры, которые легко найти в Интернете, следует использовать внимательно. Ошибки в работе (использовании) объекта XMLHttpRequest отследить непросто.
Общий ответ и частный диалог
Общий ответ сервера - обычная страница, именуемая главной от того, что называется index и с нее начинается сайт, то есть с нее расходятся ссылки на прочие доступные страницы. Впрочем, если посетитель знает имена этих прочих страниц, они в его понимании будут не менее главными, чем та, которую обозначил разработчик. Так выглядит классическая модель, сразу все: общий дизайн и функционал, ориентированный на всех посетителей.
Частный диалог - это продолжение предыдущей сессии посетителя. Сайт уже знает, что он делал, что его интересовало, какие были просмотрены страницы и отложил это в своей памяти, что-то записал в cookies браузера.
Используется два основных запроса к серверу для загрузки сайта и работы с ним: POST и GET. Результатом запроса является страница целиком. На полученной странице посетитель может активировать те или иные события, настроенные на действия над определенными элементами страницы.
События элементов страницы
Элемент страницы может быть кнопкой поиска информации, означающей - взять содержимое текстового поля и найти то, что в ней написал посетитель. Событие может возникнуть на элементе меню, рисунке, текстовом поле. В любом случае будет запущена JavaScript-функция, которая может выполнить AJAX-запрос следующим образом:
InitXML('../Mphp/scSrvPhpWord.php?cTask=GoPage' + '&cOwnerCode=' + cOwnerCode
+ '&cSessionCode=' + cSessionCode + '&cActiveItem=' + cActiveItem);
При этом функция InitXML() определена так (переменная var scXHR должна быть описана за пределами функции):
function InitXML (scURL) {
scXHR = null;
if (window.XMLHttpRequest)
{ try
{ scXHR = new XMLHttpRequest();
} catch (e) {}
} else
if (window.ActiveXObject)
{ try
{ scXHR = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e)
{ try
{ scXHR = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {}
}
}
if (scXHR)
{
scXHR.open('GET', scURL);
scXHR.onreadystatechange = WaitReplySC;
scXHR.send(null);
};
}
Эта функция получает URL и инициирует запрос по нему. Асинхронный ответ придет, как только отработает скрипт, указанный в URL (в данном случае - scSrvPhpWord.php, расположенный в папке ../Mphp/ относительно root сайта), и запустится функция WaitReplySC(), на вход которой поступит XML-ответ сервера, включая заголовок и содержание.
Ответ сервера
Собственно сервер представляет собой PHP-скрипт - программу, которая начинается с установки существенных условий, загрузки необходимых объектов, предварительной подготовки, которая зависит от целей разработчика:
namespace PhpOffice\PhpWord;
ini_set('display_errors',1);
error_reporting(E_ALL ^E_NOTICE);
ignore_user_abort(true);
set_time_limit(12);
use PhpOffice\PhpWord\MphpObj\scDocuments;
require_once 'PhpOffice/PhpWord/Autoloader.php';
\PhpOffice\PhpWord\Autoloader::register();
Представленное начало указывает на отметку всех ошибок, запрещает останавливать скрипт при отключении пользователя и устанавливает ограничение времени выполнения на случай зацикливания - 12 секунд. Далее подключается библиотека PhpOffice\PhpWord для работы с документами *.docx.
Поскольку показанный выше AJAX-вызов ('...cTask=GoPage' + '&cOwnerCode=' + cOwnerCode + '&cSessionCode=' + cSessionCode + '&cActiveItem=' + cActiveItem) - это четыре GET-переменные, которых может и не быть, следует проверить их фактическое наличие:
$cTask = (isset($_GET['cTask']))? $_GET['cTask'] : '';
$cOwnerCode = (isset($_GET['cOwnerCode'])) ? $_GET['cOwnerCode'] : '';
$cSessionCode = (isset($_GET['cSessionCode'])) ? $_GET['cSessionCode'] : '';
$cActiveItem= (isset($_GET['cActiveItem'])) ? $_GET['cActiveItem'] : '';
После выполнения подготовительных действий скрипт принимает решение:
switch ($cTask) {
case 'GoPage': // (это вызов при первоначальной загрузке или обновлении страницы)
$cOwnerCode = 'cOwner';
$cSessionCode = 'cSession';
$cContents = 'cContents';
$cStatus = 'cStatus';
$cHtml = iconv ('UTF-8', 'CP1251', 'кодировка элемента');
$cActiveItem = iconv ('UTF-8', 'CP1251', 'значения переменных');
$cReply = "scSrvRM|GoPage|set|{$cOwnerCode}`{$cSessionCode}|{$cContents}`{$cStatus}|{$cHtml}|{$cActiveItem}";
break;
}
и заключительная часть скрипта:
header("Content-Type: text/xml; accept-charset=utf-8");
header("Cache-Control: no-cache");
echo '<?xml version="1.0" encoding="UTF-8" ?>';
$cReply = iconv('CP1251', 'UTF-8', $cReply); // преобразование из 'CP1251' в 'UTF-8'
echo $cReply;
Получение ответа клиентом
На странице, загруженной в браузер, было установлено, что как только сервер подготовит ответ, он будет обработан функцией WaitReplySC:
function WaitReplySC() {
try {
if (scXHR.readyState == 4) {
if (scXHR.status == 200) { // обработка ответа
var TestReply = scXHR.responseText;
if ((TestReply.indexOf('Parse error') > 0) ||
(TestReply.indexOf('Notice') > 0)) alert(scXHR.responseText);
var cData = scXHR.responseText;
var aData = cData.split('|');
var cCmd = aData[1];
var cPos = aData[2];
var aOwnerSession = aData[3].split('`');
cOwnerCode = aOwnerSession[0];
var cSessionCode = aOwnerSession[1];
var aContentStatus = aData[4].split('`');
var cContent = aContentStatus[0];
var cStatus = aContentStatus[1];
var cHTML = aData[5]; // HTML-ответ сервера
var cVarValues = aData[6]; // значения переменных для форм
switch (cCmd) {
case 'GoPage':
var dTestLine = document.getElementById('scTestLine');
dTestLine.innerHTML = 'Reply = [' + cOwnerCode + ', '
+ cSessionCode + ', '
+ cContent + ', '
+ cStatus + ', '
+ cHTML + ', '
+ cVarValues + ']';
break;
}
} else {
document.getElementById('scAreaStatus').innerHTML = "Error!!!";
}
}
} catch(e) {}
}
Таким образом, используя эти AJAX-примеры, при загрузке страницы в браузере получим (в элементе scTestLine):
Reply = [cOwner, cSession, cContents, cStatus, кодировка элемента, значения переменных]
О представленном коде, jQuery и WordPress
Страница в браузере и текст скрипта записаны в кодировке UTF-8, потому используется функция iconv() для преобразования русских букв. В остальном скелет представленного кода очень прост и легко может быть повторен для любой конкретной цели.
Изменению подлежит только обработка ответа сервера в функции WaitReplySC() и собственно код скрипта, который формирует этот ответ. Вызовы функции InitXML (для конкретного scURL и соответствующих ему данных) размещаются в обработчиках событий на элементах страницы и определяют смысловую нагрузку этих элементов.
Представленные AJAX-примеры ориентированы на «ручное» использование технологии.
В различных система управления сайтами (СМС) описанные возможности представлены по-разному, как правило, в стиле той или иной специфики. Например, возможности jQuery AJAX реализуются вызовами функций jQuery.ajax() либо более высокий уровень: jQuery.get() и jQuery.post(). В качестве параметра передается url и settings (набор пар ключ+значение). jQuery.ajax() возвращает XMLHttpRequest-объект.
Для отслеживания результата jQuery предлагает функцию-методы: XHR.done() - успешное завершение запроса. XHR.fail() - обработка ошибки.
Метод jqXHR.done() являтся альтернативой обработчика успешного завершения AJAX-запроса. Заменяет устаревший метод jqXHR.success().
Аналогично использование на Wordpress AJAX-технологии. Здесь все уже имплантировано в саму систему управления сайтом, нужно только использовать предлагаемые конструкции. В документация предлагается подробное описание.
Применение AJAX существенно зависит от выбранного инструментария, хотя ручной вариант может быть применен параллельно или в дополнение к выбранной системе управления сайтом, той или иной версии jQuery. Последнюю полезно отработать самостоятельно, поскольку практически все современные СМС используют ее, но каждая по своему.
Классический пример применения
Простое и показательное применение AJAX - корзина в интернет-магазине. Страницы магазина всегда наполнены товарами, хотя в реальности их может и не быть. Перезагрузка обычно занимает существенное время, но когда посетитель выбирает товар, он может всегда от него сразу отказаться либо изменить выбранный другим, что на сайте всегда желательно отображать быстро.
Обычно это реализуется в виде корзины и пометок возле выбранных товаров. Без использования AJAX динамичное изменение этих элементов проблематично.
AJAX-скрипты, реализующие механизмы добавления/удаления товаров в корзину, стали де факто во многих СМС.
Для обычной передачи данных через AJAX форма может быть выполнена обычным образом (для ввода имени и пароля):
<form name='fWelcome' action='index.php' method='post'>
<div id='scWelcomeLabel' style='left: 0px; top: 12px;'>Имя:</div>
<div id='scWelcomeLabel' style='left: 0px; top: 35px;'>Пароль:</div>
<input type='text' name='cName' value='' id='scWelcomeField' title='Имя' style='left: 56px; top: 8px;'>
<input type='text' name='cPass' value='' id='scWelcomeField' title='Пароль' style='left: 56px; top: 31px;'>
</form>
<div id='scWinClose' onclick='JavaScript: scfWelcomeCancel();' title='Закрыть окно'></div>
<div id='scWelcomeGo' onclick='JavaScript: scfWelcomeGo();'>Вход</div>
Здесь обработчик:
function scfWelcomeGo() {
var cName = document.fWelcome.cName.value;
var cPass = document.fWelcome.cPass.value;
InitXML('../Mphp/scSrvPhpWord.php?cTask=CheckWelcome'
+ '&cName=' + cName
+ '&cPass=' + cPass);
}
передает на сервер для проверки введенные посетителем имя и пароль. Скрипт проверяет наличие полученной информации в таблице пользователей и отправляет обратно ответ, на основании которого соответствующий скрипт на странице выводит сообщение (выполняет действие) для зарегистрированного посетителя или сообщает, что такого пользователя нет, и нужно пройти процедуру регистрации.