ここに私のAJAX関数があります:
/**
* Send an AJAX request
*
* @param url The URL to call (located in the /ajax/ directory)
* @param data The data to send (will be serialised with JSON)
* @param callback The function to call with the response text
* @param silent If true, doesn't show errors to the user
* @param loader The element containing "Loading... Please wait"
*/
AJAX = function(url,data,callback,silent,loader) {
var a,
attempt = 0,
rsc = function() {
if( a.readyState == 4) {
if( a.status != 200) {
if( a.status > 999) { // IE sometimes throws 12152
attempt++;
if( attempt < 5)
send();
else if( !silent) {
alert("HTTP Error "+a.status+" "+a.statusText+"<br />Failed to access "+url);
}
}
else if(!silent) {
alert("HTTP Error "+a.status+" "+a.statusText+"\nFailed to access "+url);
}
}
else {
callback(JSON.parse(a.responseText));
}
}
},
to = function() {
a.abort();
attempt++;
if( attempt < 5)
send();
else if( !silent) {
alert("Request Timeout\nFailed to access "+url);
}
};
data = JSON.stringify(data);
var send = function() {
if( loader && attempt != 0) {
loader.children[0].firstChild.nodeValue = "Error... retrying...";
loader.children[1].firstChild.nodeValue = "Attempt "+(attempt+1)+" of 5";
}
a = new XMLHttpRequest();
a.open("POST","/ajax/"+url,true);
a.onreadystatechange = rsc;
a.timeout = 5000;
a.ontimeout = to;
a.setRequestHeader("Content-Type","application/json");
a.send(data);
};
send();
};
一般的な考え方は、リクエストを 5 回まで試行することです。IE が異常な HTTP エラー (12xxx) で失敗したり、サーバーが応答しないことがあります。
私が抱えている問題は、abort()
呼び出しが接続を中止しているように見えないことです。テストするために、単純な PHP スクリプトを作成しました。
<?php
sleep(60);
touch("test/".uniqid());
die("Request completed.");
?>
touch()
呼び出しは、現在のファイルを作成します。uniqid()
変更時刻を見ると、sleep(60)
終了時刻がわかります。
予想される動作:
リクエストが送信され
ます。5 秒後、テキストが「Error... Retying... Attempt 2/5」に変わります。
上記を Attempt 5/5 まで繰り返し、失敗します。
PHP ファイルへの 5 回の呼び出しが中止され、"test" フォルダーに 5 秒間隔で 5 つのファイルが存在するか、ignore_user_abort がオフになっているために存在しません。
観察された動作 (IE9):
リクエストが送信され
ます 試行テキストが表示され、必要に応じて変更されます
5 回試行した後、エラー メッセージが表示されます
5 分間、ページを読み込めません。
サーバー上には、1 分間隔で 5 つのファイルがあります。
サーバー側では、「タイムアウト」エラーメッセージがブラウザに表示されてから数分後にリクエスト 3、4、および 5 が送信されているため、これをどうすればよいかわかりません。
違いがある場合、AJAX 呼び出しを行うページは iframe にあります。iframe をリロードします (を使用iframe.contentWindow.location.reload()
しても問題は解決しません。これら 5 つのリクエストが通過するのを待ちます。
なぜこうなった?どうすれば修正できますか?
編集:開発者ツールを使用してテストを再度実行し、ネットワーク アクティビティを監視しました。結果は次のとおりです。
URL Method Result Type Received Taken Initiator
/ajax/testto (Aborted) 0 B < 1 ms (Pending...)
/ajax/testto (Aborted) 0 B 125 ms (Pending...)
/ajax/testto (Aborted) 0 B 125 ms (Pending...)
/ajax/testto (Aborted) 0 B 125 ms (Pending...)
/ajax/testto (Aborted) 0 B 124 ms (Pending...)