Ajaxで通信中に他画面に遷移するとエラー処理が走ってしまうという現象に出くわしました。
これが、Win7のFirefoxのみで現象が発生して、GoogleChrome、IEでは発生しないというクセモノ……。(そもそも、要件にFirefox対応がないのに、突っ込まれまして、対応することになりました……。)
発生したコード
以下のように書いてたんですけど、これだとFirefoxは「fail」オプションのエラー処理が走ってしまう。
※システムがわかるようなもろもろのところは適宜削除・修正しています。
function loadInfoFunction() {
$.ajax({
type : "POST",
url : "path",
dataType : "json",
data : {id: 1}
}
}).done(function(data) {
// 実行処理
}).fail(function(xmlHttpRequest, textStatus, errorThrown) {
// エラー処理
});
}
ぐぬぬ……。
調べていくと、対処法が2種類でてきた。

現在、関わっているシステムだと後者が有効でしたので、そちらを詳しく書いてきます。
対処法
上のブログだと、さらに外部リンクがあって、本来はここのお話しに対処法が書かれています。
JQueryは、ユーザーがブラウザからURLを更新するか、リンクをクリックするか、URLを変更することによって、ページから離れた場所に移動するとエラーイベントをスローします。
だから、エラーが発生した場合に、判断する条件を加えているのですね。
上のajax通信を修正すると以下のようになります。
function loadInfoFunction() {
$.ajax({
type : "POST",
url : "path",
dataType : "json",
data : {id: 1}
}
}).done(function(data) {
// 実行処理
}).fail(function(xmlHttpRequest, textStatus, errorThrown) {
if(xmlHttpRequest.readyState == 0 || xmlHttpRequest.status == 0)
return; // it's not really an error
else
// エラー処理
});
}
つまり、何を判断しているの?
上のソースを見る限り、エラーになった場合、判断条件が増えています。
自分の勉強のため、詳しくしらべてみました。
XMLHttpRequest は、クライアントとサーバーの間でデータを伝送するための機能をクライアント側で提供する APIです。
まず、XMLHttpRequest.readyStateプロパティは、リクエストの状態を unsigned short 型の値で返します。
| 値 | 状態 | 説明 |
|---|---|---|
| 0 | UNSENT | open() がまだ呼び出されていない。 |
| 1 | OPENED | send() がまだ呼び出されていない。 |
| 2 | HEADERS_RECEIVED | send() が呼び出され、ヘッダーとステータスが通った。 |
| 3 | LOADING | ダウンロード中。responseText は断片的なデータを保持している。 |
| 4 | DONE | 一連の動作が完了した。 |
もうひとつのxmlHttpRequest.statusプロパティは、リクエストに対するレスポンスのステータスを unsigned short 型の値で返します。この値は HTTP リザルトコードです。たとえば、リクエストが成功した場合、200を返します。
HTTP リザルトコードが0になる場合を調べていくと、さまざまなパターンがあるようですね。しかも、サーバーからではなく、ブラウザが返すエラーだったり。通信が切断されていたり、時間以内に通信が帰ってこなかった場合に発生します。
上の記事を見る限り、FirefoxはHTTPリザルトコードが408(request timeout)の場合、0を返すそうで。
0: Timeout (通信タイムアウト)って認識で問題なさそう。
突き詰めていくと、以下のブログのように、エラーハンドリングするのがいいのかなって思います。
まとめ
クロスブラウザ対応はなかなか難しいですね。ブラウザの仕様によって対応が変わってきます。あと、Ajax通信にもっと詳しくなっていきたいですね。今回まとめた記事、ご参考になれば幸いです。