JavaScript:xmlhttpRequest Ready State 1でランダムにスタックします
-
25-09-2019 - |
質問
私は、情報の指定されたサブネットアドレスを照会するWindowsガジェット(「ブラウザ」を意味するインターネットエクスプローラー)に取り組んできました。今、それは時々これを比較的速いペース(約5秒ごと)で行い、十分に機能します。しかし、時にはそれはReady State 1で立ち往生し、永遠にそこにとどまることがあります。ガジェットがxmlhttprequestを取得して情報を取得するための関数をやり直そうとすると、ガジェットの複数のインスタンスを開いてから1つを除くすべてを閉じると、これは容易に複製できます。その時点で、まだ開いているものは、ほとんど常にこの状態で立ち往生します。同じWebサイトにアクセスすることと関係があるかもしれないと感じています。または、移行中に停止し、別のものが機能するのを防ぐXMLHTTPRequestsが停止されていることに関係しているだけかもしれません。以下は関連するコードです。
//Reference to this for the inner function
var me = this;
var request = new XMLHttpRequest();
request.onreadystatechange = onReadyStateChange;
var url = this.url;
//Make the URL random to prevent being cached
url += ("&a=" + ((new Date()).getTime()));
Trace(DEBUG_COMM, "Sase.updateStatus url: " + url);
request.open("GET", url, true);
request.send(); // fire off the request, calls httpRequestReadyStateChange as things continue
Trace(DEBUG_COMM, "Request sent" + request.readyState);
function onReadyStateChange() {Trace(DEBUG_COMM, "Sase.httpRequestReadyStateChange: state=" + request.readyState);
if (4 == request.readyState) {
Trace(DEBUG_COMM, "Sase.httpRequestReadyStateChange: status=" + request.status);
if (request.status == 200) {
Trace(DEBUG_COMM, "retrieved html: " + request.responseText);
var results = request.responseText;
var resultsString = request.responseText.toString();
Trace(DEBUG_COMM, "results String: " + resultsString);
me.ParseStatusData(resultsString);
}
else {
//me.commError(request.status);
}
request = null;
}
}
解決
まあ、私はそれを理解したようです。私はそれが未解決のリクエストであると感じていました。なぜなら、それは閉じられているときにのみ起こるからです(つまり、サーバーとの通信中にそれらの1つが閉じている場合、それは永遠に通信し続け、他の誰もサーバーにアクセスできません)。そうだと思われます。私は複数の領域でコードをいくつか変更しましたが、基本的にはガジェットが閉じると、すべてのリクエストを中止することができます。リクエストは現在、インスタンス変数になっています(それらを中止することを可能にしますが、必要になるたびに新しいものになります。
他のヒント
これに出くわして具体的なコードの例が必要な人のために、ここに行きます。
私は同じ問題を抱えていましたが、解決策はxmlhttprequestオブジェクトを再利用して、新しい要求を開始する前にキャンセルされたことを確認することでした。複数のAJAXリクエストを飛び回る場合、これは機能しませんが、私の場合、新しいリクエストをトリガーすると、最後のリクエストが不要になったことがわかりました。
私のページのすべての要求は、このように見える同じXmlhttprequestラッパーメソッドを通過しました。
//Declare the XMLHttpRequest object to be re-used
var global_xHttpRequest = null;
function xmlHttpHandler(type, params, complete, postData) {
//Prevents an issue where previous requests get stuck and new ones then fail
if (global_xHttpRequest == null) {
global_xHttpRequest = new XMLHttpRequest();
} else {
global_xHttpRequest.abort();
}
//Parse out current URL
var baseURL = window.location.host;
var svc = "https://" + baseURL + "/processAction?";
var url = svc + params;
global_xHttpRequest.open(type, url, true);
//Add the callback
global_xHttpRequest.onreadystatechange = complete;
global_xHttpRequest.send(postData);
}
このように使用できます:
xmlHttpHandler("GET", params, completeFnc);