今回、この状況に直面して初めて知ったのでメモ。
ブラウザ上でAjaxを使用した通信を行う(ブラウザからサーバーへgetリクエストを送る)際に発生しました。
Ajaxで送るgetリクエスト
$.get( "/addpoint" , { "id" : id , "pt" : point }, function(result){callback(result);} );
このとき生成されるURLは http://hogehoge/addpoint?id=xxx&point=yyy になります。
IEで起こったここと
xxxとyyyの値が以前と同じだった場合(同じURLになる場合)キャッシュしてあるレスポンスを返してくる。
つまり、
IE( °⊿°) < 「URLが同じなんだから結果も同じだよね。」
と判断して、サーバーに聞きにいかずに最初の結果を返し続けるわけです。
(上記で言うと変数resultが常に同じ値-最初にリクエストした時の結果)
ちなみに他のブラウザではこのような処理は行われていないよう。
困ること
確かに無駄な通信は減りますが、URLが同じでもサーバーから違う結果が帰ってくることを期待している場合困ったことになります。
(今回の場合は、サーバー側でパラメーター値分の加算/減算が行われることを想定)
サーバーが異なる結果を用意していても、リクエストが送られないので問い合わせられないわけです。
いやあ、まさか、そんなことがあるなんて思いもよりませんでした。
対策
以下のような対策があるようです。
- POST送信しましょう
- リクエスト毎に変動する値をパラメーターに追加しましょう(サーバー側では捨てられる)
- getリクエストのHTTPヘッダに「If-Modified-Since」を設定しましょう
現在は、「リクエスト毎に変動する値をパラメーターに追加」しています。
パラメーターとしては「1970年1月1日午前0時からのミリ秒」を与えています。
$.get( "/addpoint" , { "id" : id , "pt" : point, "tm" : new Date().getTime() //捨てられる }, function(result){callback(result);} );
これでIEでも毎回サーバーにリクエスト送信するようになりました。
改良
無駄な通信が発生しているのでリクエストのHTTPヘッダに「If-Modified-Since」を設定するのがいいのかもしれない。そもそもPOSTにするのがいいのかな。
— 追記
以下のようにIf-Modified-Sinceを設定するようにしました。
$.ajax({ beforeSend : function( req ){ req.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT"); }, cache : true, type:'GET', url:'/addpoint', dataType:'json', data:{ "id" : id , "pt" : point }, success: function(result) { callback(result); } });
JQueryで用意されている簡易版メソッド$.getではなく、$.ajaxを使うことでリクエストのHTTPヘッダに値を設定できました。
教えてもらったこと
WindowsPhoneアプリケーション開発をする際にも同様のことが発生しているようです。