3

: コードが問題の原因 (の一部) である可能性を考えて、ajax 呼び出し以外のコードを貼り付けました。ただし、そうではないと思いますので、もう少し下 のajaxand関数に焦点を当てたほうがよいでしょう。また、この質問には私のコードが解読しにくいというコメント (賛成票付き) があるので、それが問題を見つけるための鍵であると証明できるかどうかを明確にする必要があるかどうかを喜んで明確にしたいと思います。ありがとう。jAjax


つまりね。私が使用するのは$.ajax()メソッドだけなので、jQueryを捨てようとしています.1つの機能だけにjQueryのようなライブラリ全体を含めるのはIMOクレイジーです。とにかく、メソッドのすべての機能を必要としない$.ajaxため、独自のajax関数を作成しました。

問題は、それが機能していないことです。その理由がわかりません。サーバーにオブジェクトを送信しようとしています (具体的には、コントローラーの ajaxAction - Zend FW を使用)。以下は、javascript コードと、firebug コンソールが教えてくれることの要約です。

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);
        }
    });
}

私が Ajax リクエストを作成しようとした 4 つの方法:

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
  1. jAjax({data:{foo:'bar'}},getUrl());:これはうまくいきます:

    []{"ajax":true,"controller":"index","action":"ajax","module":"default","identity":{},"data":{"foo":" Bar"}} パラメーター: data[foo] 'bar' ソース: data%5Bfoo%5D=Bar (FB コンソールの [POST] タブから) ヘッダー: application/x-www-form-urlencoded; charset=UTF-8
    これはすべて次の URL に送信されました: http://www.foo.bar/index/ajax?data%5Bfoo%5D=bar

  2. ただし、これは機能しません。

    []{"ajax":true,"controller":"index","action":"ajax","module":"default","identity":{}} は FB の応答 POST タブ: JSON データ: {foo:'Bar'} ソース: {"data":{"Foo":"Bar"}} (ただし、同じ URL はケース 1 です) ヘッダー: json; 文字セット=UTF-8

  3. これは大きな問題です: 完全なリクエスト URL はケース 1 の URL と同じです。ヘッダーも同様ですが、FB コンソールの [POST] タブを見ると (リクエストを調べます)、これが唯一の違いです:

    ケース 1: パラメータ: data[foo] 'bar' ソース: data%5Bfoo%5D=Bar
    この場合、[パラメータ] セクションは表示されません: ソース: data%5Bfoo%5D=Bar

  4. パススルーするのを忘れたと思われる URL を除いて、case2 と同じencodeURIです。このケースは、今のところそれほど重要ではありません。ケース3の何が問題なのかを理解した瞬間に、これが機能するようになると思います/願っています.

4 つのケースすべてで、要求が送信され、受信されます。コントローラーのアクションは次のとおりです。

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??');
    }
}

JSON 文字列を受け取っているので、リクエストが送信され、正しいXMLHttpRequestヘッダーが含まれていることは確かです。では、JSON オブジェクトを投稿できないのはなぜですか? さらに要点: ケース 3 が機能しないのはなぜですか? 私が気付いていないjQueryは何をしていますか? ケース 1 は機能するが、ケース 3 は機能しないのはなぜですか?

PS: 関係ないかもしれませんが、狂った瞬間に this:ret.setRequestHeader('Connection','close');を関数に追加しようとしましたが、送信されたヘッダーで、まったく同じようにキープアライブに設定されajaxていることに気付きました。Connectionおそらく、これは誰かが何がうまくいかなかったのかについての手がかりを与えるでしょうか?

前もって感謝します

4

1 に答える 1

1

何が間違っていたのか疑問に思う人のために:

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

最後に「d」を付けて「x-www-form-urlencoded」にする必要があります。

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

形式化されたオブジェクトの送信が機能するようになり、jQuery を取り除くことができます :-)

于 2012-05-11T14:19:00.203 に答える