Вопрос по javascript, ajax, zend-framework, json, php – Ajax-запрос JavaScript против jQuery $ .ajax

3

NOTEЯ вставил больше кода, чем просто вызовы ajax, на случай, если этот код (часть) является причиной проблемы. Однако я не думаю, что это так, поэтому вам, вероятно, лучше сосредоточиться наajax а такжеjAjax функционирует немного ниже.
Также отметим, что, поскольку в этом вопросе есть комментарий (с повышенным голосом), в котором говорится, что мой код трудно расшифровать, я с удовольствием уточню, что нужно прояснить, если это может оказаться ключом к нахождению проблемы.
Благодарю.

Вот в чем дело. Я пытаюсь отказаться от jQuery, так как я использую только$.ajax() метод, и включение целой библиотеки, такой как jQuery, только для одной функции - безумие IMO. Мне даже не нужна полная функциональность$.ajax метод в любом случае, следовательно, я написал свой собственныйajax функция.

Проблема в том, что она не работает, и я не могу понять, почему. Я пытаюсь отправить объекты на сервер (а именно: ajaxAction в контроллере - используя Zend FW). Ниже приведен код javascript и краткое изложение того, что сообщает мне консоль Firebug.

<code>if (!String.prototype.trim)
{
    String.prototype.trim = function()
    {
        "use strict";
        return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    };
}

function getUrl(action,controller)
{
    var base,uri;
    base = window.location.href.replace('http://'+window.location.host,'');
    if (base.length > 1)
    {
        base = base.substring(1,base.length).split('/');
        controller = controller || base[0];
        base[0] = controller || base[0];
        base[1] = action || base[1];
        return '/'+base.join('/');
    }
    controller = controller || 'index';
    action = action || 'ajax';
    return base+controller+'/'+action;
}

function formalizeObject(obj,recursion)
{
    recursion = recursion || false;
    if (typeof obj !== 'object')
    {
        throw new Error('no object provided');
    }
    var ret = '';
    for (var i in obj)
    {
        if (!obj.hasOwnProperty(i) || typeof obj[i] === 'function')
        {
            continue;
        }
        if (recursion)
        {
            ret +='['+i+']';
        }
        else
        {
            ret += (ret.length > 0 ? '&' : '') + i.toString(); 
        }
        if (typeof obj[i] === 'object')
        {
            ret += formalizeObject(obj[i],true);
            continue;
        }
        ret += '='+obj[i].toString();
    }
    if (recursion)
    {
        return ret;
    }
    return encodeURI(ret);
}

function success()
{
    if (this.readyState===4 && this.status===200)
    {
        console.log(this.responseText);
    }
}

function ajax(str,url,method,json)
{
    var ret;
    json = json || false;
    str = str || {};
    method = method || 'POST';
    url = url || getUrl();
    str = 
    str = (typeof str === 'object' ? str : {data:str});
    try
    {
        ret = new XMLHttpRequest();
    }
    catch (error)
    {
        try
        {
            ret= new ActiveXObject('Msxml2.XMLHTTP');
        }
        catch(error)
        {
            try
            {
                ret= new ActiveXObject('Microsoft.XMLHTTP');
            }
            catch(error)
            {
                throw new Error('no Ajax support?');
            }
        }
    }
    if (typeof ret !== 'object')
    {
        throw new Error('No Ajax, FFS');
    }
    ret.open(method, url, true);
    ret.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    ret.setRequestHeader('Content-type', (json ? 'application/json' : 'application/x-www-form-urlencode'));
    ret.onreadystatechange = success;
    ret.send((json ? JSON.stringify(str) : formalizeObject(str)));
    return true;
}

function jAjax(str,url)
{
    $.ajax(
    {
        url : url,
        data: str,
        type: 'POST',
        success: function(res)
        {
            console.log(res);
        }
    });
}
</code>

Четыре способа, которыми я пытался сделать запрос Ajax:

<code>jAjax({data:{foo:'bar'}},getUrl());//1
jAjax({data:{foo:'bar'}},getUrl(),true);//2
ajax({data:{foo:'bar'}},getUrl());//3
ajax({data:{foo:'bar'}},getUrl(),true);//4
</code>

jAjax({data:{foo:'bar'}},getUrl());: This works just fine:

[]{"ajax":true,"controller":"index","action":"ajax","module":"default","identity":{},"data":{"foo":"Bar"}} Parameters: data[foo] 'bar' And Source: data%5Bfoo%5D=Bar (from POST tab in FB console) Header: application/x-www-form-urlencoded; charset=UTF-8
All of this was sent to the following url: http://www.foo.bar/index/ajax?data%5Bfoo%5D=bar

This doesn't work, however:

[]{"ajax":true,"controller":"index","action":"ajax","module":"default","identity":{}} is the response POST tab in FB: JSON data: {foo:'Bar'} source: {"data":{"Foo":"Bar"}} (but same url is case 1) Header: json; charset=UTF-8

This is the big one: the full request url is identical to url from case 1, as are the headers BUT when I look at the POST tab in the FB console (inspect the request) This is the only difference I can find:

case 1: Parameters: data[foo] 'bar' Source: data%5Bfoo%5D=Bar
In this case, I can't see the Parameters section, only: Source: data%5Bfoo%5D=Bar

Identical to case2, except for the url, which I think I forgot to pass through encodeURI. This case is less important for now. I think/hope I'll get this working the moment I figure out what's wrong with case 3.

Во всех 4 случаях запрос отправлен и получен. Действие контроллера заключается в следующем:

<code>public function ajaxAction()
{
    $this->_helper->layout->disableLayout();
    $this->getHelper('viewRenderer')->setNoRender();
    $this->_helper->getHelper('AjaxContext')->addActionContext( 'ajax' , 'json' )
                                            ->initContext('json');
    if($this->getRequest()->isPost() && $this->getRequest()->isXmlHttpRequest())
    {
        echo json_encode(array_merge(array('ajax'=>true),$this->_getAllParams()));
    }
    else
    {
        throw new Exception('no ajax call made??');
    }
}
</code>

Поскольку я получаю строку JSON, я уверен, что запрос отправлен и имеет правильныйXMLHttpRequest заголовок. Почему тогда я не могу публиковать объекты JSON? Более того: почему дело 3 не работает? Что делает jQuery, о котором я не знаю? Что делает вариант 1 работающим, а не случай 3?

PS: Это может быть неуместно, но в момент безумия я попытался добавить это:ret.setRequestHeader('Connection','close'); кajax функции, но я заметил, что в заголовке, который был отправлен,Connection был установлен, чтобы сохранить жизнь все же. Возможно, это дает кому-то ключ к пониманию того, что пошло не так?

заранее спасибо

Вы можете проверитьzepto.jsЭто попытка быть легкой альтернативой jquery, и вы можете проверить их ajax-функцию. Zombaya
@JFDion: Это не просто размер библиотеки jQuery, которую я хочу избежать. JQuery великолепен, без сомнения, но он медленный. В основном вы говорите: вы могли быnot задайте этот вопрос и оставьте все как есть и просто примите, что это работает, не зная почему. Elias Van Ootegem
Ваши мясистые части вашего поста трудно расшифровать, отчасти из-за размера и шума. Ну, по крайней мере для меня. goat
@ chris: правда, я не должен был публиковать весь код, там есть вероятность, что где-то там есть проблема (хотя я думаю, что нет).ajax а такжеjAjax функции являются те, на которых нужно сосредоточиться. @Zombaya: я изучу его, хотя на самом деле пытаюсь избавиться от фреймворка, поэтому я не заинтересован в его замене другим ... но кто знает, это может быть именно то, что мне нужно Elias Van Ootegem
Вы можете сохранить свою библиотеку jquery, даже для 1 функции. При надлежащем контроле кэша и распаковке ваших файлов по запросу трассировка становится минимальной, поскольку клиент загрузит ее только один раз и сохранит ее в кэше во временных файлах браузера. JF Dion

Ваш Ответ

1   ответ
1

ret.setRequestHeader('Content-type', 'application/x-www-form-urlencode');

Должен был быть "x-www-form-urlencoded", с "d" в конце:

ret.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

отправкаformalized объект теперь работает, и я могу избавиться от jQuery :-)

Похожие вопросы