[英]Chrome not handling jquery ajax query
我在jquery中有以下查詢。 它正在讀取使用Nginx的長輪詢模塊設置的Nginx訂閱/發布對的“發布”地址。
function requestNextBroadcast() {
// never stops - every reply triggers next.
// and silent errors restart via long timeout.
getxhr = $.ajax({
url: "/activity",
// dataType: 'json',
data: "id="+channel,
timeout: 46000, // must be longer than max heartbeat to only trigger after silent error.
error: function(jqXHR, textStatus, errorThrown) {
alert("Background failed "+textStatus); // should never happen
getxhr.abort();
requestNextBroadcast(); // try again
},
success: function(reply, textStatus, jqXHR) {
handleRequest(reply); // this is the normal result.
requestNextBroadcast();
}
});
}
該代碼是聊天室的一部分。 發送的每條消息都以null rply(200 / OK)回復回復,但數據已發布。 這是在數據返回時讀取訂閱地址的代碼。
使用超時,聊天室中的所有人都會每隔30到40秒發送一條簡單的消息,即使他們沒有輸入任何內容,因此這段代碼需要讀取大量數據 - 每40秒至少有2條消息可能更多。
該代碼在EI和Firefox中100%堅實。 但在Chrome中,大約5個讀取失敗了。
當Chrome失敗時,它會超時46秒。
該日志顯示任何時候一個/活動網絡請求未完成。
我已經在這個代碼上爬了3天了,嘗試各種想法。 每當IE和Firefox工作正常而Chrome失敗時。
我看到的一個建議是使呼叫同步 - 但這顯然是不可能的,因為它會長時間鎖定用戶界面。
編輯 - 我有一個部分解決方案:代碼現在是這個
function requestNextBroadcast() {
// never stops - every reply triggers next.
// and silent errors restart via long timeout.
getxhr = jQuery.ajax({
url: "/activity",
// dataType: 'json',
data: "id="+channel,
timeout: <?php echo $delay; ?>,
error: function(jqXHR, textStatus, errorThrown) {
window.status="GET error "+textStatus;
setTimeout(requestNextBroadcast,20); // try again
},
success: function(reply, textStatus, jqXHR) {
handleRequest(reply); // this is the normal result.
setTimeout(requestNextBroadcast,20);
}
});
}
結果有時會延遲回復,直到$ delay(15000)發生,然后排隊的消息太快到達了。 我一直無法通過這種新安排刪除消息(僅通過netwrok optomisation測試)。
我非常懷疑網絡問題的延遲是什么 - 所有機器都是我真實機器中的虛擬機,並且本地局域網中沒有其他用戶。
編輯2(美國中部時間星期五2:30) - 更改代碼以使用承諾 - 並且操作的POST開始顯示相同的症狀,但接收方開始正常工作! (???? !!! ???)。 這是POST例程 - 它處理一系列請求,以確保一次只有一個請求。
function issuePostNow() {
// reset heartbeat to dropout to send setTyping(false) in 30 to 40 seconds.
clearTimeout(dropoutat);
dropoutat = setTimeout(function() {sendTyping(false);},
30000 + 10000*Math.random());
// and do send
var url = "handlechat.php?";
if (postQueue.length > 0) {
postData = postQueue[0];
var postxhr = jQuery.ajax({
type: 'POST',
url: url,
data: postData,
timeout: 5000
})
postxhr.done(function(txt){
postQueue.shift(); // remove this task
if ((txt != null) && (txt.length > 0)) {
alert("Error: unexpected post reply of: "+txt)
}
issuePostNow();
});
postxhr.fail(function(){
alert(window.status="POST error "+postxhr.statusText);
issuePostNow();
});
}
}
關於8中的一個動作,對handlechat.php的調用將超時並顯示警報。 警報一旦確定,所有排隊的消息都會到達。
而且我還注意到,在寫出其他人會看到的消息之前,手機呼叫已停止。 我想知道是否可能是一些奇怪的處理會話數據的PHP。 我知道它仔細排隊呼叫,以便會話數據不被破壞,所以我一直小心使用不同的瀏覽器或不同的機器。 只有2個php工作線程,但是php不用於處理/活動或靜態內容的服務。
我也認為它可能是nginx工作者或php處理器的短缺,所以我提出了這些。 現在更難以讓事情失敗 - 但仍然可能。 我的猜測是/ activity調用現在失敗30次,並且根本不丟棄消息。
謝謝你們的投入。
調查結果摘要。
1)Chrome中的一個錯誤已經在代碼中存在了一段時間。
2)幸運的是,可以將錯誤顯示為未發送的POST,並且當它超時時,它會使Chrome處於這樣一種狀態,即重復POST將成功。
3)用於存儲$ .ajax()的返回的變量可以是本地的或全局的。 新的(promises)和舊的格式調用都觸發了bug。
4)我沒有找到工作或避免錯誤的方法。
伊恩
我與Chrome有一個非常相似的問題。 我正在進行Ajax調用,以便每秒從服務器獲取時間。 顯然,Ajax調用必須是異步的,因為如果沒有,它會在超時時凍結接口。 但是,一旦Ajax調用之一失敗,每個后續調用都是如此。 我首先嘗試將超時設置為100毫秒,這在IE和FF中運行良好,但在Chrome中卻沒有。 我最好的解決方案是將類型設置為POST,並為我解決了chrome的錯誤:
setInterval(function(){
$.ajax({
url: 'getTime.php',
type: 'POST',
async: true,
timeout: 100,
success: function() { console.log("success"); },
error: function() { console.log("error"); }
});
}, 1000);
更新:我認為這里的實際根本問題是Chrome的緩存方式。 似乎當一個請求失敗時,該緩存會被緩存,因此后續請求永遠不會發生,因為Chrome會在啟動后續請求之前獲得緩存失敗。 如果您轉到Chrome的開發人員工具並轉到“網絡”標簽並檢查每個正在發出的請求,就可以看到這一點。 在失敗之前,每秒都會對getTime.php發出ajax請求,但是在1次失敗之后,永遠不會啟動后續請求。 因此,以下解決方案對我有用:
setInterval(function(){
$.ajax({
url: 'getTime.php',
cache: false,
async: true,
timeout: 100,
success: function() { console.log("success"); },
error: function() { console.log("error"); }
});
}, 1000);
這里的變化是,我禁止緩存到這個Ajax查詢,但為了這樣做,類型選項必須是GET或HEAD,這就是我刪除' type: 'POST'
'的原因(GET是默認的)。
嘗試將您的輪詢功能移動到網絡工作者,以防止鉻合金凍結。 否則你可以嘗試使用jquery對象的ajax .done()。 一個人總是在我的鉻合金。
我覺得getxhr應該以“var”為前綴。 您是否每次都想要一個完全獨立的新請求而不是在成功/失敗處理過程中覆蓋舊請求? 可以解釋為什么添加setTimeout時行為“改進”。 我也可能遺漏了一些東西;)
評論不會格式化代碼,因此重新發布為第二個答案:
我認為Michael Dibbets正在使用$ .ajax.done - 延遲模式將處理推送到事件循環的下一輪,我認為這是需要的行為。 請參閱: http : //www.bitstorm.org/weblog/2012-1/Deferred_and_promise_in_jQuery.html或http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/
我會嘗試這樣的事情:
function requestNextBroadcast() {
// never stops - every reply triggers next.
// and silent errors restart via long timeout.
getxhr = jQuery.ajax({
url: "/activity",
// dataType: 'json',
data: "id="+channel,
timeout: <?php echo $delay; ?>
});
getxhr.done(function(reply){
handleRequest(reply);
});
getxhr.fail(function(e){
window.status="GET error " + e;
});
getxhr.always(function(){
requestNextBroadcast();
});
注意:我很難找到Promise.done和Promise.fail的回調參數的文檔:(
也許它可以通過改變推模塊設置(有幾個)來解決 - 你能發布這些嗎?
從我的頭頂:
我還會使用類似Charles的東西來查看網絡/應用程序層上究竟發生了什么
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.