Лабораторная работа 7. Гостевая книга с использованием технологий Ajax и PHP AJAX, Ajax (ˈeɪdʒæks, от англ. Asynchronous Javascript and XML — «асинхронный JavaScript и XML») — подход к построению интерактивных пользовательских интерфейсов веб-приложений, заключающийся в «фоновом» обмене данными браузера с веб-сервером (рисунок 1). Рисунок 1 – Модель обмена данных с сервером в синхронном (слева) и асинхронном (справа) режиме В результате, при обновлении данных веб-страница не перезагружается полностью, и веб-приложения становятся более быстрыми и удобными. AJAX - это концепция использования нескольких смежных технологий. AJAX базируется на двух основных принципах: 1. Использование технологии динамического обращения к серверу «на лету», без перезагрузки всей страницы полностью, например: 2 с использованием XMLHttpRequest (основной объект); через динамическое создание дочерних фреймов; через динамическое создание тега <script>; через динамическое создание тега <img>, как это реализовано в google analytics. 2. Использование DHTML для динамического изменения содержания страницы. В качестве формата передачи данных могут использоваться фрагменты простого текста, HTML-кода, JSON или XML. Преимущества: экономия трафика; уменьшение нагрузки на сервер; ускорение реакции интерфейса. Недостатки: отсутствие интеграции со стандартными инструментами браузера (не работает кнопка «Назад», невозможность сохранения закладки) динамически загружаемое содержимое недоступно поисковикам (если не проверять запрос, обычный он или XMLHttpRequest); усложнение проекта; требуется включенный JavaScript в браузере. Принцип работы Скрипт состоит из двух частей: 1. Клиентская часть исполняется на стороне клиента, пишется на JavaScript. 2. Серверная часть: исполняется на сервере, может быть написана на любом языке программирования, понимающем GET/POST запросы. Этапы написания клиентской части: 1. Сбор и подготовка информации для отправки запроса на сервер. 2. Создание экземпляра объекта XMLHttpRequest. 3 3. Установка для него функции обработчика события onreadystatechange. Это событие наступает при каждой смене состояния объекта XMLHttpRequest (см. таблицу внизу). Данная функция по сути является основной частью скрипта, поскольку именно в ней происходит обработка ответа сервера. 4. Открытие соединения с указанием типа запроса (GET или POST), URL серверной части, флага асинхронного режима и имени и пароля пользователя (если необходимо). 5. Непосредственно отправка запроса; 6. Обработка ответа серверной части. Методы и свойства класса XMLHttpRequest приведены в Приложении А. Пример 1. Обработка данных в php-скрипте Файл index.html <html> <head> <script> /*переменная для хранения объекта запроса*/ var xmlHttp=null; /*создание объекта запроса*/ function createRequest() { try{ //создаем объект запроса для Firefox, Opera, Safari, Chrome xmlHttp = new XMLHttpRequest(); } catch(e){ //создаем объект запроса для Internet Explorer try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e){ try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e){ xmlHttp = null; } } if(xmlHttp == null)alert("Браузер не поддерживает AJAX!"); } /*отправка запроса*/ function sendRequest() {/*получаем объект запроса*/ 4 createRequest(); /*Устанавливаем соединение и передаем параметры асинхронно*/ xmlHttp.open("GET", "ajax.php?param1=яблоки&param2=груши", true); /*Указываем функцию для обработки данных*/ xmlHttp.onreadystatechange = MyFunc; /*Отправляем запрос*/ xmlHttp.send(null); } /*обрабатываем ответ*/ function MyFunc() { if(xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { alert(xmlHttp.responseText); } else { alert("Ошибка обработки запроса!"); } } } </script> </head> <body> <h3>Получение данных с сервера с помощью php-скрипта</h3> <input value="Получить параметры с сервера" type="button" onClick="sendRequest();" /> </body> </html> Файл ajax.php <?php /*Получаем параметры*/ $param1 = $_GET['param1']; $param2 = $_GET['param2']; /*Отсылаем ответ клиенту*/ echo("Вы прислали $param1 и $param2"); ?> Пример 2. Динамическое обновление контента (с использованием jQuery) Файл index.html <html> <head> <meta http-equiv="Content-Type" content="text/html;Charset=UTF-8"> <script type="text/javascript" src="jquery.js"></script> </head> <body> <form> 5 <input id="btn1" type="button" value="Страница 1"> <input id="btn2" type="button" value="Страница 2"> </form> <div id="content"></div> <script> $(document).ready(function(){ $('#btn1').click(function(){ $.ajax({ /*Обращение к файлу page1.html для получения контента*/ url: "page1.html", /*Результаты запросов не кэшируются*/ cache: false, /*При успешном выполнении запроса, управление переходит r функции, которая получает контент в качестве параметра и записывает его контейнер*/ success: function(html){ /*запись в контейнер*/ $("#content").html(html); } }); }); $('#btn2').click(function(){ $.ajax({ url: "page2.html", cache: false, success: function(html){ $("#content").html(html); } }); }); }); </script> </body> </html> 6 Задание Создать гостевую книгу с использованием технологии Ajax и встроить ее в сайт, созданный на предыдущих лабораторных работах. Рекомендуемый интерфейс Гостевой книги представлен на рисунке 2. Вы можете представить Гостевую книгу в любом формате. Основное назначение – публикация сообщений на странице. Сообщения может оставлять только авторизированный пользователь. Рисунок 2 – Интерфейс Гостевой книги Порядок работы: 1. В базе данных MySQL создайте таблицу MESSAGES для хранения сообщений пользователей с полями: ID_m – идентификатор сообщения; Date_m – дата сообщения; Time_m – время сообщения; Text_m – текст сообщения. 2. Создайте файл bd.php, содержащий настройки соединения с базой данных. 3. Создайте файл index.php с областью для ввода и отображения данных. Обратите внимание на названия классов. Эти названия классов использованы в файле add_m.js для асинхронной обработки данных, код которого приведен в п.5. <h3>Гостевая книга</h3> <div id='notes'> <div class='note'> <div class='note_date_time'> <!--Дата и время из БД -- > </div> <div class='note_text'> <!-- Текст сообщения из БД -- > </div> </div> </div>; 7 Данные для текстовых полей необходимо получить из таблицы MESSAGES с помощью запроса на выборку «SELECT…» 4. Создайте файл add_m.php для вставки записей в таблицу базы данных с помощью SQL-оператора «INSERT INTO…» из области, формируемой тегами <textarea> в файле index.php. Дату и время создания сообщения можно получить следующим образом: $date = date("d.m.Y"); $time = date("H:i:s"); 5. Создайте файл add_m.js для асинхронной обработки данных. var xmlHttpAddNote = createXmlHttpRequestObject(); function createXmlHttpRequestObject () {//для хранения ссылки на объект XMLHttpRequest var xmlHttp; //этот участок кода работает во всех браузерах, за исключением ie6 и более старых версий try{// попытаться создать объект XMLHttpRequest xmlHttp = new XMLHttpRequest(); } catch (e){// для браузера ie6 или более старых версий var XmlHttpVersions = new Array ("MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"); //попробовать все возможные версии объекта, начиная с наибольшей, пока какая-либо попытка не увенчается успехом for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++) { try {// попытаться создать объект XMLHttpRequest xmlHttp = new ActiveXObject(XmlHttpVersions[i]); } catch (e) {} } } // вернуть созданный объект или вывести сообщение об ошибке if (!xmlHttp) alert("Ошибка создания объекта XMLHttpRequest"); else return xmlHttp; } function addNote(){ if(xmlHttpAddNote){ 8 try { if (xmlHttpAddNote.readyState == 4 || xmlHttpAddNote.readyState == 0) { oState = document.getElementById("state"); oState.innerHTML = "Добавление заметки..."; text = document.getElementById("note_text").value; var params = "text="+text; xmlHttpAddNote.open("POST", "add_note.php", true); xmlHttpAddNote.setRequestHeader("Content-Type", "application/xwww-form-urlencoded"); xmlHttpAddNote.onreadystatechange = handleAddNote; xmlHttpAddNote.send(params); } else setTimeout('addNote()', 1000); } catch(e) { alert("Ошибка: " + e.toString()); } } } function handleAddNote(){ //когда readyState = 4, мы можем прочитать ответ if (xmlHttpAddNote.readyState == 4){ // продолжать, только если статус HTTP равен "Ок" if (xmlHttpAddNote.status == 200){ try{ // обработать ответ, полученный от сервера readAddNote(); } catch (e) {// вывести сообщение об ошибке alert("Ошибка чтения ответа: " + e.toString()); } } else {// Вывести сообщение о состоянии alert("Возникли проблемы во время получения данных:\n" + xmlHttpAddNote.statusText); 9 } } } function readAddNote(){ // прочитать сообщение, полученное от сервера var response = xmlHttpAddNote.responseText; /*если ответ не содержит ни одного символа или он равен 0, то предполагаем, что получили сообщение об ошибке от сервера*/ if (response.length == 0) throw(response.length == 0 ? "Ошибка сервера" : response); if (response == 0) { oState.innerHTML = "Ошибка добавления заметки."; } else { var note = document.createElement("div"); note.innerHTML = response; document.getElementById("notes").appendChild(note); oState.innerHTML = ""; } } 10 Приложение А Вернуться к примерам Таблица 1 - Методы класса XMLHttpRequest Метод Описание abort() отменяет текущий запрос getAllResponseHeaders() возвращает полный список заголовков в виде строки getResponseHeader(headerName) возвращает заголовка значение HTTP- указанного open(method, url, async, userName, определяет метод, URL, асинхронность и password) другие параметры запроса send(data) отправляет запрос на сервер, данных нет то параметр null если setRequestHeader(label, value) добавляет HTTP-заголовок к запросу overrideMimeType(mimeType) позволяет указать mime-type документа; Внимание: метод отсутствует в Internet Explorer! Таблица 2 -Свойства класса XMLHttpRequest Свойство Описание onreadystatechange обработчик события, которое происходит при каждой смене состояния объекта readyState возвращает текущее состояние объекта (0— неинициализирован, 1—открыт, 2—отправка данных, 3— получение данных и 4—данные загружены) responseText текст ответа на запрос responseXML текст ответа на запрос в виде XML status возвращает HTTP-статус в виде числа (404 — «Not Found», 200 — «OK» и т. д.) statusText возвращает статус в виде строки («Not Found», «OK» и т. д.)