[英]AJAX response text undefined
我關注以下2個帖子:
我已經以相同的方式實現了代碼。 但是我越來越
未定義不是函數
無論我在代碼中使用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);
}
});
}
}
})();
這將進行以下更改:
將代碼包含在IIFE(自執行函數)中,因此在代碼塊中聲明的變量不是全局變量。
從document.body.innerHTML += html
更改為使用document.body.appendChild()
以避免每次都重新創建所有DOM元素。
聲明var html
所以它是一個局部變量,而不是另一個偶然的全局變量。
使用Array.prototype.slice.call()
從document.getElementsByTagName("a")
復制結果,因此數組不會隨着文檔的修改而改變,從而使我們能夠准確地進行迭代。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.