簡體   English   中英

AJAX響應文本未定義

[英]AJAX response text undefined

我關注以下2個帖子:

  1. Ajax responseText返回為未定義
  2. 無法返回xmlhttp.responseText?

我已經以相同的方式實現了代碼。 但是我越來越

未定義不是函數

無論我在代碼中使用callback()函數的任何地方。

碼:

function articleLinkClickAction(guid,callback){

    var host = window.location.hostname;
    var action = 'http://localhost:7070/assets/find';
    var url = action + '?listOfGUID=' + guid.nodeValue;
    console.log("URL "+url);
    xmlhttp = getAjaxInstance();
    xmlhttp.onreadystatechange = function() 
    {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {

            var response = JSON.parse(xmlhttp.responseText);
            console.log(response);
            console.log(xmlhttp.responseText);
            callback(null, xmlhttp.responseText);// this is line causing error
        }
        else{
            callback(xmlhttp.statusText);// this is line causing error
        }
    };
    xmlhttp.open("GET", url, true);
    xmlhttp.send(null);
}

我從以下代碼中調用它:

var anchors =  document.getElementsByTagName("a");
        var result = '';
        for(var i = 0; i < anchors.length; i++) {
            var anchor = anchors[i];

            var guid = anchor.attributes.getNamedItem('GUID');
            if(guid)
            {
                articleLinkClickAction(guid,function(err, response) { // pass an anonymous function
                    if (err) {
                        return "";

                    } else {
                        var res =  response;
                        html = new EJS({url:'http://' + host + ':1010/OtherDomain/article-popup.ejs'}).render({price:res.content[i].price});
                        document.body.innerHTML += html;
                    } 
                });
            }
        }

您正在為xmlhttp使用單個全局變量,並嘗試同時運行多個ajax調用。 這樣,每個后續的ajax調用都將覆蓋先前的ajax對象。

我建議在xmlhttp聲明的前面添加var ,以使其成為函數中的局部變量,這樣每個ajax請求都可以具有自己的單獨狀態。

function articleLinkClickAction(guid,callback){

    var host = window.location.hostname;
    var action = 'http://localhost:7070/assets/find';
    var url = action + '?listOfGUID=' + guid.nodeValue;
    console.log("URL "+url);
    // add var in front of xmlhttp here to make it a local variable
    var xmlhttp = getAjaxInstance();
    xmlhttp.onreadystatechange = function() 
    {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {

            var response = JSON.parse(xmlhttp.responseText);
            console.log(response);
            console.log(xmlhttp.responseText);
            callback(null, xmlhttp.responseText);// this is line causing error
        }
        else{
            callback(xmlhttp.statusText);// this is line causing error
        }
    };
    xmlhttp.open("GET", url, true);
    xmlhttp.send(null);
}

將來,您應該考慮使用Javascript的strict模式,因為在嚴格模式下不允許使用這些“偶然的”全局變量,並且會報告錯誤,以使您明確地將所有變量聲明為局部變量或全局變量(無論您打算使用哪個變量)。

我不能說這是否是導致代碼無法正常工作的唯一錯誤,但這肯定是一個嚴重錯誤,妨礙了正常操作。


這是另一個重要的問題。 在您的真實代碼(在私人聊天中看到)中,您正在使用:

document.body.innerHTML += html

在這樣獲得的HTMLCollection的迭代中間:

var anchors = document.getElementsByTagName("a");

在此代碼中, anchors將是實時HTMLCollection。 這意味着,只要在文檔中添加或刪除錨元素,它將動態更改。 但是,每次執行document.body.innerHTML += html都會從頭開始重新創建整個body元素,從而完全更改anchors HTMLCollection 首先,執行document.body.innerHTML += html只是一種不好的做法。 相反,您應該將新元素附加到現有DOM。 我不確切知道該html中包含什么,但是您應該只創建一個div,將HTML放入其中,然后像這樣附加div:

var div = document.createElement("div");
div.innerHTML = html;
document.body.appendChild(div);

但是,這還不是全部,因為如果這個新的HTML包含更多的<a>標記,則anchors的實時HTMLCollection仍將更改。

我建議更改此代碼塊:

    var anchors =  document.getElementsByTagName("a");
    var result = '';
    for(var i = 0; i < anchors.length; i++) {
        var anchor = anchors[i];

        var guid = anchor.attributes.getNamedItem('GUID');
        if(guid)
        {
            articleLinkClickAction(guid,function(err, response) { // pass an anonymous function
                if (err) {
                    return "";

                } else {
                    var res =  response;
                    html = new EJS({url:'http://' + host + ':1010/OtherDomain/article-popup.ejs'}).render({price:res.content[i].price});
                    document.body.innerHTML += html;
                } 
            });
        }
    }

對此:

(function() {
    // get static copy of anchors that won't change as document is modified
    var anchors = Array.prototype.slice.call(document.getElementsByTagName("a"));

    var result = '';
    for (var i = 0; i < anchors.length; i++) {
        var anchor = anchors[i];

        var guid = anchor.attributes.getNamedItem('GUID');
        if (guid) {
            articleLinkClickAction(guid, function (err, response) { // pass an anonymous function 
                if (err) {
                    //return ""; 
                    console.log('error : ' + err);
                } else {
                    var res = response;
                    var html = new EJS({
                        url: 'http://' + host + ':1010/OtherDomain/article-popup.ejs'
                    }).render({
                        price: res.content[i].price
                    });
                    var div = document.createElement("div");
                    div.innerHTML = html;
                    document.body.appendChild(html);
                }
            });
        }
    }
})();

這將進行以下更改:

  1. 將代碼包含在IIFE(自執行函數)中,因此在代碼塊中聲明的變量不是全局變量。

  2. document.body.innerHTML += html更改為使用document.body.appendChild()以避免每次都重新創建所有DOM元素。

  3. 聲明var html所以它是一個局部變量,而不是另一個偶然的全局變量。

  4. 使用Array.prototype.slice.call()document.getElementsByTagName("a")復制結果,因此數組不會隨着文檔的修改而改變,從而使我們能夠准確地進行迭代。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM