読者です 読者をやめる 読者になる 読者になる

XMLHttpRequest でのステータスコード 304 (Not Modified) について

IE の Ajax (XMLHTTP) で、通信が行われたかキャッシュが使われたかを判定する方法 - IT戦記 を読んで、レスポンスのステータスコード見るのが本来のやり方なのではと思い、試してみたら意外な結果になった。

テスト

content.txt を採りに行って表示するだけの下記のサンプルをそれぞれブラウザで表示して、リンクをクリックしたときレスポンスコードがどうなるか試してみた。

Internet Explorer
<html>
<head>
<script type="text/javascript">
function test(){
  var req = new ActiveXObject('Microsoft.XMLHTTP');
  req.onreadystatechange = function(){
    if (req.readyState == 4) {
      alert(req.status);
    }
  };
  req.open('GET', 'content.txt');
  req.send();
}
</script>
</head>
<body>
<p><a href="#" onclick="test(); return false;">test</a></p>
<div id="content"></div>
</body>
</html>
Internet Explorer 以外のブラウザ用
<html>
<head>
<script type="text/javascript">
function test(){
  var req = new XMLHttpRequest();
  req.onreadystatechange = function() {
    if (req.readyState == 4) {
      alert(req.status);
    }
  };
  req.open("GET", "./content.txt", true);
  req.send(null);
}
</script>
</head>
<body>
<p><a href="#" onclick="test(); return false;">test</a></p>
<div id="content"></div>
</body>
</html>

結果は全てレスポンスコード 200 の OK となってしまった。次にサーバのログをみてみよう。

HTTP サーバのログを確認

Apache 2.2側のログを追ってみたところ下記のようになった。IE と Opera は content.txt を二回目以降にアクセスにいっていないことがわかる。FirefoxSafari はリクエストする度にサーバへアクセスしている。

Internet Explorer 7.0
192.168.1.10 - - [01/Jun/2008:09:21:02 +0900] "GET /test/test-ie.html HTTP/1.1" 200 399 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; .NET CLR 1.1.4322)"
192.168.1.10 - - [01/Jun/2008:09:21:05 +0900] "GET /test/content.txt HTTP/1.1" 200 8 "http://192.168.1.19/test/test-ie.html" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; .NET CLR 1.1.4322)"

※二回目以降からアクセスに行かないのでログがない。

Firefox 2.0
192.168.1.10 - - [01/Jun/2008:09:22:16 +0900] "GET /test/test.html HTTP/1.1" 200 434 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"
192.168.1.10 - - [01/Jun/2008:09:22:29 +0900] "GET /test/content.txt HTTP/1.1" 200 8 "http://192.168.1.19/test/test.html" "Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"
192.168.1.10 - - [01/Jun/2008:09:22:32 +0900] "GET /test/content.txt HTTP/1.1" 304 - "http://192.168.1.19/test/test.html" "Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"
Safari 3.1
192.168.1.10 - - [01/Jun/2008:09:24:24 +0900] "GET /test/test.html HTTP/1.1" 200 434 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13"
192.168.1.10 - - [01/Jun/2008:09:24:29 +0900] "GET /test/content.txt HTTP/1.1" 200 8 "http://192.168.1.19/test/test.html" "Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13"
192.168.1.10 - - [01/Jun/2008:09:24:31 +0900] "GET /test/content.txt HTTP/1.1" 304 - "http://192.168.1.19/test/test.html" "Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13"
Opera 9.2
192.168.1.10 - - [01/Jun/2008:09:26:06 +0900] "GET /test/test.html HTTP/1.1" 200 434 "-" "Opera/9.23 (Windows NT 6.0; U; ja)"
192.168.1.10 - - [01/Jun/2008:09:26:08 +0900] "GET /test/content.txt HTTP/1.1" 200 8 "http://192.168.1.19/test/test.html" "Opera/9.23 (Windows NT 6.0; U; ja)"

※二回目以降からアクセスに行かないのでログがない。

まとめ

基本的に XMLHttpRequest はサーバが 304 (Not Modified) を返しても 200 (OK) として返す。IE, Opera はそもそも変更確認にも行かない。*1
下記の参考ページなどをみてみたが Ajax でのキャッシュ処理について、あまり深追いしない方がいいのではないかと思う。最適化にはサーバーサイドの設定も必要であることと、そもそも XMLHttpRequest の実装が意識させないようになっているためだ。
キャッシュが必ず効かないようにしたいときは、ダミー引数を与えるというのは確実かつ現実的な方法だろう。
参考)

*1:ブラウザの設定はデフォルトにしてある