jQuery.getJSON() の罠


とある Web アプリケーションを作っていたときのこと、Firefox ではまともに動くのに、IE ではバージョンを問わず機能しないことがあった。調べてみると、(珍しいことに)IE の方が仕様に則った正しい動作をしていたためであった。

最初に結論を言うと、毎回違う結果が欲しいのなら、$.getJSON() よりも $.post() を使えって話。

GET メソッドによるサーバーアクセスはブラウザにキャッシュされる。同じパラメータでのアクセスを繰り返そうとしても、ブラウザによっては、ローカルキャッシュを返すことでサーバーへのアクセスを行わない。これは GET メソッドの冪等性を考えれば自明のことだ。

冪等 – Wikipedia

冪等性は、大雑把に言って、ある操作を1回行っても複数回行っても結果が同じであることをいう概念である。

(中略)

HTTP の GET 要求は冪等とみなされる。Webの機構は基本的にその前提で要求結果をキャッシュに保持する。HTTP の POST 要求(フォーム送信に使われる)は冪等とはみなされないため、POST 要求はキャッシュされない。

実際の例で言うと、

$.getJSON(url, {
    year: 2011
    ,month: 10
}, function(data) {
    $('#log').html(data.text);
});

このスクリプトを実行しても毎度毎度同じ結果しか表示しない。これを防ぐ方法は二通りある。

パラメータにタイムスタンプを付加する

$.getJSON(url, {
    year: 2011
    ,month: 10
    ,ts: new Date().getTime()
}, function(data) {
    $('#log').html(data.text);
});

毎回違う URL でアクセスすることによって強制的にキャッシュさせない。

POST メソッドを使う

$.post(url, {
    year: 2011
    ,month: 10
}, function(data) {
    $('#log').html(data.text);
}, 'json');

意味の無いパラメータを付加するよりは、こっちの方がいいんじゃなかろうか。どちらでも好きな方をどうぞ。