webew
Войти » Регистрация
 
JavaScript :: AJAX

Пользуемся AJAX-объектом

12 августа 2008, 11:47

AJAX (Asynchronous JavaScript and XML) — термин, который не так давно вошел в лексикон создателей WEB-приложений. Он означает целую совокупность технологий, объединяемых в рамках одного интерфейса и позволяющих отправлять запросы к серверу без перезагрузки страницы.

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

AJAX-объект

/*
В основу объекта лег код, приводимый в книге:
Dave Crane, Eric Pascarello, Darren James: Ajax in Action
*/

// Базовый объект
var net = new Object();
// Состояния запроса
net.READY_STATE_UNINITIALIZED = 0;
net.READY_STATE_LOADING = 1;
net.READY_STATE_LOADED = 2;
net.READY_STATE_INTERACTIVE = 3;
net.READY_STATE_COMPLETE = 4;
// Конструктор
// key - Ключ запроса в массиве requestsHash
// method - метод отправки запроса (POST, GET)
// url - URL скрипта на сервере, который обработает запрос
// params - параметры запроса (test=1&flag=2)
// onload - callback-функция, обработчик после загрузки
// onerror - callback-функция, обработчик в случае ошибки
// contentType - тип контента запроса (text/html)
// headers - прочие заголовки, кроме content-type, например, Expires
net.ContentLoader = function(key, method, url, params, onload, onerror, contentType, headers) {
      this.hashKey = key;
      // Свойство для рапознавания браузеров, не поддерживающих request
      this.unrequestBrowser = false;
      // request - объект
      this.req = null;
      this.onload = onload;
      // Если её нет, вызывается дефолтный обработчик
      this.onerror = (onerror) ? onerror : this.defaultError;
      // Вызываем метод для генерации запроса
      this.loadXMLDoc(method, url, params, contentType, headers);
}
// Все методы записаны в прототип
net.ContentLoader.prototype = { // Methods
      // loadXMLDoc - метод, для генерации request-запроса
      loadXMLDoc : function(method, url, params, contentType, headers) {
            if (!method) method="GET";
            if (!contentType && method=="POST") contentType='application/x-www-form-urlencoded';
            if (window.XMLHttpRequest) {
                  this.req=new XMLHttpRequest();
            } else if (window.ActiveXObject) {
                  this.req=new ActiveXObject("Microsoft.XMLHTTP");
            } else {
                  this.unrequestBrowser = true;
                  return;
            }
            if (this.req) {
                  try {
                        this.req.open(method,url,true);
                        if (contentType){
                              this.req.setRequestHeader('Content-Type', contentType);
                        }
                        if (headers) {
                              for (var h in headers) {
                                    this.req.setRequestHeader(h,headers[h]);
                              }
                        }
                        var loader=this;
                        this.req.onreadystatechange=function() {
                              loader.onReadyState.call(loader);
                        }
                        this.req.send(params);
                  } catch (err){
                        this.onerror.call(this);
                  }
            }
      },
      // onReadyState - метод для обработки ответов сервера
      onReadyState : function() {
            var req=this.req;
            var ready=req.readyState;
            if (ready==net.READY_STATE_COMPLETE) {
                  var httpStatus=req.status;
                  if (httpStatus==200 || httpStatus==0) {
                        this.onload.call(this);
                  } else {
                        this.onerror.call(this);
                  }
            }
      },
      // defaultError - метод обработки ошибок по умолчанию
      defaultError : function() {
            alert("error fetching data!"+"\n\nreadyState:"+this.req.readyState +"\nstatus: "+this.req.status+"\nheaders: "+this.req.getAllResponseHeaders());
      }
}
// Массив для хранения нескольких запросов
var requestsHash = [];
// Функция, создающая новый экземпляр объекта net.ContentLoader
// Записывает запросы в requestsHash
// Возвращает свойство unrequestBrowser
function setAjaxRequest(method, url, params, onload, onerror, contentType, headers) {
      // Check of necessary parameters
      if (!url) {
            alert("Necessary parameters are not specified");
            return;
      }
      requestsHash.push(new net.ContentLoader(requestsHash.length, method, url, params, onload, onerror, contentType, headers));
      return requestsHash[requestsHash.length - 1].unrequestBrowser;
}

Подготовка

Для создания так называемого асинхронного запроса и получения ответа потребуются некоторые условия:

  1. Серверный скрипт, который примет запрос, обработает его и выдаст ответ. В качестве примера здесь будет использован PHP-скрипт ajaxDemo.php, который на выходе отдает XML-дерево такого вида:
    <xml>
    <result>Success!</result>
    <error></error>
    </xml>
  2. Функция, которая отправит запрос. Она уже есть (setAjaxRequest) и встроена в приведенный выше AJAX-объект, ей и воспользуемся.
  3. Функции-обработчики, которые примут ответ (или возможную ошибку) и надлежащим образом отреагируют. Они будут вызваны как callback-функции и this для них вернет ссылку на экземпляр объекта net.ContentLoader.
// Функция обработки ответа
function ansHandler() {
      // Для обработки ответа можно изпользовать два основных свойства request-объекта
      // responseText - вернет ответ в качестве текстовой переменной
      // responseXML - вернет XML-ответ
      // Последовательно воспользуемся обоими свойствами
      alert(this.req.responseText);
      // XML-структурой можно управлять более эффективно
      // Например, получать значения отдельных узлов
      var xml = this.req.responseXML.firstChild;
      if (xml.nodeType != 1) xml = xml.nextSibling; // fix for Opera
      var result = xml.getElementsByTagName("result")[0].firstChild.nodeValue;
      alert("result = " + result);
}
// Функция обработки ошибок
function errorHandler() {
      alert("При обработке запроса произошла ошибка, повторите попытку снова");
}

Формирование и отправка запроса

function doit() {
      var method = "GET";
      var url = "http://2007.fastcoder.ru/demo/ajaxDemo.php";
      var params = false; // Без параметров
      var onload = ansHandler;
      var onerror = errorHandler;
      var contentType = headers = false; // Без заголовков
      return setAjaxRequest(method, url, params, onload, onerror, contentType, headers);
}

И какой-нибудь HTML-элемент, например ссылку, для отправки запроса:

<a onclick="return doit();" href="#">Отправить запрос</a>

Замечания

  • Браузер Opera ниже версии 8.0 не поддерживает request. Собственно для них и создавалось свойство unrequestBrowser, которое возвращается всеми функциями. Если вернется true, то произойдет простой переход по ссылке.
  • Скрипт можно улучшить и расширить, но необходимый минимум (и даже больше) в этой статье имеется. Если вы нашли ошибки или пришли к выводу, что чего-то существенно не хватает — пишите.



// Все права на статью JavaScript::Пользуемся AJAX-объектом принадлежат сайту 2007.fastcoder.ru
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
NO USERPIC

rgbeast

Может ли AJAX работать в Опере ниже 8 версии?
13.08.2008, 03:14
Ответить

bur

Реализации XHR (XMLHttpRequest) в Операх ниже восьмой версии нет. Однако, можно найти обходные пути:

1) Скрытый ифрейм. Однопиксельный, не видный на странице ифрейм, будет получать данные и сабмитить форму с ними на сервер. Ответ от сервера, который придет в виде HTML, также можно обработать, поместив в этот самый ответ js-код, который свяжется с родительской страницей.

2) Динамическое создание тегов <script>. В этом случае на странице таким вот способом создаются теги скрипт:
var srcipt = document.createElement("script");
srcipt.type = "text/javascript";
script.src = "/url.js?=1234"
document.body.appendChild(script);

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

Оба способа в свое время использовались (и до сих пор используются) для кроссбраузерной асинхронной загрузки. Однако, благодаря большему удобству XHR и тому, что все современные браузеры его поддерживают, эти два способа постепенно выходят из употребления.
13.08.2008, 11:55
Ответить
NO USERPIC

mirkus

извените за беспокойство.
можно на примере чуть подробнее содержимое файла ajaxDemo.php показать. (только решил начать изучать я).
Дело в том что на локалке у меня
ajaxDemo.php выдает окно <result>Success!</result>
<error>Error</error>
,а как я понял,он должен выдавать либо содержимое тэга <result>Success!</result>,
либо содержимое тэга <error>Error</error>.
содержимое файла
<?php
echo'<xml>
<result>Result</result>
<error>ERROR!</error>
</xml>';
?>
-
весь js скрипт код приведенный на странице,
я запихал в один файл ajax.js
что я сделал не правильно ?
почему функции ansHandler() и errorHandler() не работают?
-
05.11.2008, 10:35
Ответить

bur

Вообще не важно какое XML-дерево отдает серверный скрипт, лишь бы оно было правильно построено и отдавало нужную информацию.
Про text/xml и кодировку в http-заголовке также не забудьте.
Насчет неработоспособности - поделитесь ссылкой на страницу где не работает.
05.11.2008, 12:14
Ответить
NO USERPIC

mirkus

на локалке тестю.
в общем все равно,учить матчасть придётся,как я понял (xml)

ajaxDemo.php выдает окно
<result>Success!</result>
<error>Error</error>

исходник:
<?php
echo'<xml>
<result>Result</result>
<error>ERROR!</error>
</xml>';
?>
--
как я понял,просто как текстовое сообщение выходит,в окне,содержимое ajaxDemo.php
--
в любом случае спасибо за статью, понял принцип работы в ajax ,благодаря ей
написал свой хелоу ворд,.
А далее буду разбираться =).






05.11.2008, 13:42
Ответить
NO USERPIC

roulwin

Ошибка возникает в браузере IE (у меня версия 8) при "var params = false;" выводит сообщение "При обработке запроса произошла ошибка, повторите попытку снова" - на остальных браузерах - всё нормально!
Если установить "var params = "";" - то всё отображается.
25.05.2010, 00:37
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2024 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100

Реклама: