【jQuery】IE + Ajax関連でいくつかの条件が重なった場合に表示されるエラーとその解決策

【最終更新日:2010年10月23日】

基本事項〜IEについて〜

Internet Explorerでは、NULLもしくは未定義の変数に対して、
存在しないメンバ変数を呼び出そうとするとエラーが表示されます。

var hoge;
//または var hoge = null; var hoge = undefined;
alert(hoge.fuga); //←存在しないメンバ変数

『'hoge.fuga' は Null またはオブジェクトではありません。』


他のブラウザでも、画面に表示はされないものの、エラーとして
判断されています。
Firebugでは『hoge is undefined』または『hoge is null』と
表示されます。


jQueryAjax処理中に上のエラーが発生する条件

【実例】
下記をIE7で開いてみてください。
前節と同じエラーメッセージが表示されます。
http://www.usamimi.info/~sutara/sample/jqAjaxErrorTest/test1.html


【ソース】

【test1.html】
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<script src="jquery-1.4.2.min.js"></script>
<script>
jQuery(document).ready(function($){
ajaxTest('hoge');
ajaxTest('fuga'); //立て続けにAjax通信を行う
});
var $xhr;
function ajaxTest(txt){
if($xhr) $xhr.abort(); //まだ以前のAjax通信が実行中なら、中断する
$xhr = $.getJSON('ajax.php', {'txt':txt}, function(data){
alert(data[txt]); //いきなりdataのメンバ変数を呼び出す
});
}
</script>
</head>
</html>

ajax.php
<?php
$data;
$data[$_GET['txt']] = $_GET['txt'];
echo json_encode($data);
?>


【条件】
下記の条件がすべて満たされた場合、エラーが発生します。
  1. jQuery 1.4.2以下の1.4系である。

  2. 新たにAjax通信を行う前に、まだ以前のAjax通信が実行中なら

    前の通信のほうを中断させる処理を記述している。

  3. Ajax通信後のコールバック関数で、帰ってきたデータに対して

    いきなりそのメンバ変数を呼び出す。

  4. 立て続けにAjax通信が実行され、条件2の通信の中断が実際に行われる。


条件の検証

【1. 通信を中断する処理を削除】
エラーは発生せず、1番目と2番目のAjax通信は、どちらも成功します。
中断処理を省いたんですから当然ですが…。
http://www.usamimi.info/~sutara/sample/jqAjaxErrorTest/test2.html

【test2.html(抜粋)】
function ajaxTest(txt){
//if($xhr) $xhr.abort();
$xhr = $.getJSON('ajax.php', {'txt':txt}, function(data){
alert(data[txt]);
});
}

【2. jQueryを1.3系にする】
1番目のAjax通信は失敗するものの、エラーは表示されません。
http://www.usamimi.info/~sutara/sample/jqAjaxErrorTest/test3.html

【test3.html(抜粋)】
<script src="jquery-1.3.2.min.js"></script>

以上で、前節の条件が証明されました。


解決策

では、どうやってエラー表示を回避するのか?
IE7だけ、abortしないように分岐を設けます。

function ajaxTest(txt){
if(!$.browser.msie || $.browser.version != '7.0'){
if($xhr) $xhr.abort();
}
$xhr = $.getJSON('ajax.php', {'txt':txt}, function(data){
alert(data[txt]);
});
}

または、jQuery1.4.3以降の1.4系を使うことですね。