Javascript関連情報

更新日:2009年05月15日

jQueryのAjaxリクエスト 6

今回は、jQueryのAjax メソッドajax( options )について引数のオプションリストの中からifModified と jsonp です。

前回は、 ajax( options ) のオプションリストの中から、、error と timeout と global を試してみましたが、今回は、ifModified と jsonp です。

jQueryの取得などについては下記リンクをご参照ください。

ajax( options ) のoptions.ifModified

options.ifModifiedは、HTTP通信のIf-Modified-SinceヘッダとLast-Modifiedヘッダによるファイルの更新チェックを行います。

If-Modified-Sinceは、ブラウザ側からのリクエストヘッダで、Last-Modifiedは、サーバー側から返される最終更新日のレスポンスヘッダです。

If-Modified-Sinceは、日時を値として送ると、その時刻以降に更新されていれば、サーバーから普通のレスポンスが返り、更新されていなければ、レスポンスボディ無しで、304(not modifided)のステータスレスポンスが返ります。

HTTPでは、このヘッダを使うことで、同じファイルの送受信を何度も無駄に繰り返すことを回避できるわけですが、これは、一般的にはブラウザがキャッシュを利用して自動的に行っています。

jQueryのajaxメソッドでは、このoptions.ifModified へ true をセットすることで、If-Modified-Sinceヘッダを明示的に処理して、サーバー上のファイルが、以前受信したファイルと同じファイル(Last-Modifiedが同じ時刻)なら(つまり、更新されていなければ)、successイベントを実行せず、errorとcompleteのみを実行するといった動作を行います。

このように、JavaScriptから明示的にチェックすることで、たとえば、各ブラウザ毎の実装の違いなどを気にすることなく、サーバー上のファイルの更新日が新しい場合だけ処理を行うといった事ができます。

では、試してみましょう。下記リンクをクリックするとサンプルページが開きます。

test1

サンプルは、【ifModified:false】と【ifModified:true】のボタンがあり、それぞれに対応したリクエストが送られます。さて、結果ですが次のようになります。
【ifModified:false】
success
msg: こんにちは
status: success
complete
XHR: 
XHR.responseText: こんにちは
XHR.status: 200
status: 
--------------------------------------------------------------------------------

success
msg: こんにちは
status: success
complete
XHR: 
XHR.responseText: こんにちは
XHR.status: 200
status: 
--------------------------------------------------------------------------------


【ifModified:true】
success
msg: こんにちは
status: success
complete
XHR: 
XHR.responseText: こんにちは
XHR.status: 200
status: 
--------------------------------------------------------------------------------

error
XHR: 
status: notmodified
errorThrown: undefined
complete
XHR: 
XHR.responseText: 
XHR.status: 304
status: 
それぞれ2回以上繰り返し押してみると、【ifModified:false】の方は何度押しても成功し、success、completeイベントがともに動作していることがわかります。

これに対して、【ifModified:true】の方は、1度目は成功しますが、2度目以降は、errorイベントが発生し、ステータスは、notmodifiedを返しています。successイベントは発生せず、completeも発生はしますが、responseTextプロパティには何も入っていません。

つまり、これを使って、サーバー上のファイルが、前回と比べて更新されていなければ、作業しないということができるわけです。

今回、テストに使ったソースはつぎのとおりです。

クライアント側
<div>それぞれ2回以上繰り返し押してみてください。
  <p>
  <button id="a" class="jsbuttons">
    【ifModified:false】</button>
  <button id="b" class="jsbuttons">
    【ifModified:true】</button>
  </p>
  <p id="su1"><b>【ifModified:false】</b></p>
  <p id="su2"><b>【ifModified:true】</b></p>
</div>

<script type="text/javascript">
jQuery(function($){

  //【ifModified:false】
  $("#a")
   .click(function () {
       $.ajax( mkOption("#su1",false) );
    });

  //【ifModified:true】
  $("#b")
    .click(function () {
       $.ajax( mkOption("#su2",true) );
    });

  //$.ajaxメソッドの引数へ渡すオプションを返します
  function mkOption(selector,ifmod){
    return {
      ifModified:ifmod,
      url: "./msg.txt",
      error:function(XHR, status, errorThrown){
        $(selector)
          .append("<br><b>error</b>")
          .append("<br>  XHR: "+XHR)
          .append("<br>  status: "+status)
          .append("<br>  errorThrown: "+errorThrown)
      },
      success: function(msg,status){  
        $(selector)
          .append("<br><b>success</b>")
          .append("<br>  msg: "+msg)
          .append("<br>  status: "+status)
      },
      complete: function (XHR, textStatus) {  
        $(selector)
          .append("<br><b>complete</b>")
          .append("<br>  XHR: "+XHR)
          .append("<br>  XHR.responseText: "+XHR.responseText)
          .append("<br>  XHR.status: "+XHR.status)
          .append("<br>  status: "+status)
          .append("<hr>");
      }
    }
  }

  //タイトルに色付け
  $("#su1>b").css({"color":"red"})
  $("#su2>b").css({"color":"red"})
     
});
</script>
サーバー側./msg.txt
こんにちは
この、同一ファイル(時刻)のチェックは、jQueryの内部では、送信時にifModifiedがtrueなら、初回はIf-Modified-Sinceヘッダの値として、setRequestHeaderメソッドで、"Thu, 01 Jan 1970 00:00:00 GMT"を与えています。

つまり、1回目は、大概は1970年より新しいファイルなので、必ず受信します。

そして、2回目以降は、サーバーから受信したLast-Modifiedヘッダの値を記録して、次のIf-Modified-Sinceヘッダの値として、送出することで更新をチェックします。

参考までに、jquery-1.3.2.jsだと次のコード(3525行目)です。
// Set the If-Modified-Since header, if ifModified mode.
if ( s.ifModified )
  xhr.setRequestHeader("If-Modified-Since",
    jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );

サーバーから受け取ったLast-Modified時刻の値は、受信成功時に、 jQuery.lastModified[options.url]という配列に入れておくことで、各URLごとに個別の値が把握されています。

なお、注意したいのは、この仕組みは、サーバーから渡される最終更新日 Last-Modifiedヘッダを使ってファイルの更新を確認しますので、それを返さない場合にはうまくいかないことです。たとえば、一般の静的HTMLファイルなどと違い、PHPやPerlなどで動的に生成されるページの場合は、サーバーのプログラム側から自力でLast-Modifiedヘッダを出力する必要があります。

さて、次ページは、options.jsonpについて確認してみます。

1 2
  • 印刷する
  • ブックマークする
  • 携帯に送る
  • ブログに書く

あわせて読みたい

この記事の担当ガイド

写真

高橋 登史朗

Javascriptをはじめ、Ajax、jQueryの著書多数のガイドが、何かと最近騒がれているJa…

続きを読む

住まいには、人の個性がよく現れるもの。同じ空間をどのように使うかで、雰囲気も、快適さも大きく変わってくる。ここでは、「建築家と家を建てる」ガイド の川畑博哉氏が厳選した10軒を紹介し、建築家それぞれのこだわりのポイントを紹介しよう。建築のプロたちが考え出した、マネしたくなるアイデアが満載! さぁ、いますぐチェック!

人気Javascriptランキング

Powered by 価格.com

デジタル関連コミュニティ

北欧好きが、愛用の北欧モノを見せ合うコミュニティ

メルマガ登録

【デジタルメルマガ】オトナのオトコなら知っておきたい、PCやデジモノに関する情報をお届けします。

ショッピングカタログ

All About ウェブマガジン

女性向け

雨が楽しくなる!レイングッズ15

男性向け

マネしたくなるアイデア住宅

All About モバイル

QRコード

All Aboutがケータイで読める!

オススメ記事をメールでチェック

知識・経験を生かして、記事を書いてみませんか?