покритикуйте библиотеку )

Духовность™

Продвинутый новичок
покритикуйте библиотеку )

Вот, написал первую версию для работы с Ajax на JS для простеньких GET-запросов:

PHP:
function Ajax()
{
    /**
     * Экземпляр XMLHttpRequest.
     * 
     * @access private
     * @var object XMLHttpRequest
     */
    var req;

    /**
     * HTTP-заголовки
     * 
     * @access private
     * @var array
     */
    var httpHeaders = new Array();

    httpHeaders["If-Modified-Since"] = "Sat, 1 Jan 2000 00:00:00 GMT";
    
    /**
    * Создает объект XMLHttpRequest
    * 
    * @param void
    * @return XMLHttpRequest|null
    */
    this.createRequestObject = function()
    {
        if (window.XMLHttpRequest) {
            try {
                req = new XMLHttpRequest();
            } catch (e){}
        }
        // only IE 6 =< 
        else if (window.ActiveXObject) {
            try {
                var aVersions = ["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0", 
                                 "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp",
                                 "Msxml2.XMLHTTP", 'Microsoft.XMLHTTP'];

                for (var j in aVersions)
                {
                    try {
                        req = new ActiveXObject(aVersions[j]);
                        break;
                    } catch (e){}
                }
            } catch (e){}
        }

        if (!req)
        {
            throw new UserException('XMLHttprequest не работает в вашем броузере');
        }
    }

    this.createRequestObject();

    /**
     * Абстрактный предопределяемый метод, привязанный
     * к обработчику onreadystatechange.
     * 
     * @param void
     * @return mixed
     */
    this.observerState = function()
    {
        if (req.readyState==4) {
            if (req.status == 200) {
                alert('Метод observerState должен быть предопределен перед использованием объекта');
            }
        }

        /*
        * Пример предопределения в скрипте:
        
            var ajax = new Ajax();
            ajax.observerState = function()
            {
                if (ajax.getHttpRequest().readyState==4) {
                    if (ajax.getHttpRequest().status == 200)
                    {
                        alert(ajax.getHttpRequest().responseText)
                    }
                }
            }
        */
    }

    /**
     * Отправляет GET-запрос по адресу url
     * 
     * @param string url
     * @param boolean синхронность запроса.
     * true - асинхронный, false - синхронный
     * @return void
     */
    this.get = function(url, synchronicity)
    {

        // по умолчанию - синхронный запрос
        if (typeof synchronicity == 'undefined') 
        {
            var synchronicity = true;
        }

        req.open('GET', url, !!synchronicity);

        this.sendHeaders();

        if (synchronicity)
        {
            req.onreadystatechange = this.observerState;
        }

        req.send(null);
    }
    
    /**
     * Создает хеш-массив key => value из XML-представления ответа.
     * XML ответа должен иметь вид: <key>value</key>
     * Корневой элемент полученного XML должен иметь тег root_tag
     *
     * @access public
     * @param root_tag имя корневого тега XML-элемента.
     * @return array  
     */
    this.getXml2HashByTagName = function(root_tag)
    {
        if (typeof root_tag == 'undefined')
        {
            var root_tag = 'root';
        }

        var xmlDomDoc = req.responseXML; // объект типа xmldomdocument
        var arr = new Array();
        var nodes = xmlDomDoc.getElementsByTagName(root_tag)[0].childNodes;

        for (var i=0; i <nodes.length; i++)
        {
            if (nodes.item(i).nodeType == 1)
            {
                arr[nodes.item(i).tagName] = nodes.item(i).firstChild
                                             ? nodes.item(i).firstChild.nodeValue 
                                             : null;
            }
        }

        return arr;
    }

    /**
     * Создает хеш-массив key => value из XML-представления ответа.
     * XML ответа должен иметь вид: <mytag mykey="key">value</mytag>
     * Корневой элемент полученного XML должен иметь тег root_tag
     *
     * @access public
     * @param root_tag имя корневого тега XML-элемента.
     * @return array  
     */
    this.getXml2HashByValue = function(root_tag)
    {
        if (typeof root_tag == 'undefined')
        {
            var root_tag = 'root';
        }

        var xmlDomDoc = req.responseXML; // объект типа xmldomdocument
        var arr = new Array();
        var nodes = xmlDomDoc.getElementsByTagName(root_tag)[0].childNodes;

        for (var i=0; i <nodes.length; i++)
        {
            if (nodes.item(i).nodeType == 1)
            {
                arr[nodes.item(i).getAttribute('value')] = nodes.item(i).firstChild 
                                                           ? nodes.item(i).firstChild.nodeValue
                                                           : null;
            }
        }

        return arr;
    }

    /**
     * Возвращает стандартный объект JS, который является
     * "сериализованным" объектом в виде строки текста ответа - JSON.
     * 
     * @access public
     * @param void
     * @return object 
     */
    this.getJson2HashByKey = function()
    {
        return eval( "(" + req.responseText + ")" );
    }

    /**
     * Устанавилвает заголовок HTTP с ключом key 
     * и значением value.
     * 
     * @access public
     * @param key имя HTTP-заголовка
     * @param value значение HTTP-заголовка
     * @return void
     */
    this.setHeader = function(key, value)
    {
        httpHeaders[key] = value;
    }

    /**
     * Отправляет HTTP-заголовки.
     * 
     * @access private
     * @param void
     * @return void
     */
    this.sendHeaders = function()
    {
        for (var i in httpHeaders)
        {
            if (typeof httpHeaders[i] == 'string')
            {
                req.setRequestHeader(i, httpHeaders[i]);
            }
        }
    }

    /**
     * Возвращает экземпляр объекта XMLHttpRequest
     * 
     * @param void
     * @return object req
     */
    this.getHttpRequest = function()
    {
        return req;
    }
}
использование:

PHP:
    var ajax = new Ajax();
    // назначаем функцию для onreadystatechange 
    ajax.observerState = function() 
    {
        if (ajax.getHttpRequest().readyState == 4) {
            if (ajax.getHttpRequest().status == 200) {
                // что-то делаем с массивом ответа 
                foo (ajax.getJson2HashByKey() );
            }
        }
    }
    ajax.get("/ajax/?id=....", true);
 

vovanium

Новичок
А длиннее нельзя было метод назвать getJson2HashByKey?
Да и вообще делать подобный вызов для обработчика - глупость, зачем мне при каждом вызове писать всю эту хрень вместо того чтобы написать так

PHP:
ajax.get('url', function(){foo(ajax.json());}, true);
Методы для header'ов я бы выкинул, зачем дублировать существующие методы, а лучше бы сделал post запросы.
И зачем такое мега определение xhr для ie 6?
достаточно:
PHP:
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : (window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : null);
В общем неюзабельная она какая-то.
 

Splurov

Новичок
А какая первоначальная задача? Обучиться JS/XHR? Сложно сейчас представить проект, где не используется js-фреймворк.
 
Сверху