「キャッシュさせたくない」ではなく、「キャッシュさせたいけど、2回目のアクセスでは304を返したい(ログに残したい)」という場合の話。
Cashe-Control や Expires ヘッダを何も指定しなかった場合、たいていのブラウザは2回目のアクセスでリクエストさえよこしてこない、ということを昨日知った。
この 4.の時、リクエストがあって304が返っているのかと思っていたのだけど、それは違ったみたい。
で、このブラウザがキャッシュにあるコンテンツを表示する時に、必ず If-Modified-Since 付きリクエストをさせるにはどうしたらよいか。(サーバーは304を返したい)
ネットを見るとExpires: -1 とか Expires: 0 とか指定するといい、という話もあるけど、検証してたら、Expiresヘッダの値でブラウザの返し方がまちまちであることがわかったので、まとめておく。結論から言うと、Expires ヘッダに過去の日付を指定するのが良さそう。
If-Modified-Sinceが来る| 何も指定しない | Expires 0 | Expires -1 | Expires 過去の日付 | |
|---|---|---|---|---|
| IE 6.0 | × | ○ | ○ | ○ |
| IE 5.5 | × | ○ | ○ | ○ |
| IE 5.0 | × | ○ | ○ | ○ |
| Firefox 1.5 (Win/Mac) | × | ○ | × | ○ |
| Opera 8 (Win/Mac) | × | ○ | ○ | ○ |
| Opera 9 (Win/Mac) | × | ○ | ○ | ○ |
| Safari 1 | × | × | × | ○ |
| Safari 2 | × | × | × | ○ |
| Mac IE 5 | ○ | ※ | ※ | ※ |
MacIE5 の ※ のところは特殊で、なんと毎回 If-Modified-Sinceなしリクエスト(200が返る)。いつもながら、想像を裏切る反応です。
Expires 0 だと良さそうなのですが、Safariが理解してくれません。
というわけで、2回目のアクセスもサーバーのログに残したいよ、という場合は、
<Location /hoge>
Header Add Expires "Thu, 01 Jan 1970 00:00:00 GMT"
</Location>
みたくしておくとよさそうです。
これ、はげしくBKな気が。補足情報を知っている人がいたら教えてください。
コメントでRFCのことが出てきたので追記
Expiresヘッダについては、RFC2616 HTTP/1.1 の Header Field Definitions あたりでしょうか。
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21
HTTP-date 形式で設定せよ(MUST)となってますが、
HTTP/1.1 clients and caches MUST treat other invalid date formats, especially including the value "0", as in the past (i.e., "already expired").
とのことで、不正な日付書式、特に0は期限切れとして扱わなければならない(MUST)、とも言われています。なので、-1 や 0 については、ブラウザは対応すべきなのでしょう。
ただし、HTTP/1.0 では MUSTという言葉ではなく、
Note: Applications are encouraged to be tolerant of bad or misinformed implementations of the Expires header. A value of zero (0) or an invalid date format should be considered equivalent to an "expires immediately." Although these values are not legitimate for HTTP/1.0, a robust implementation is always desirable.
というわけで、対応しておいた方がいいよ(always desirable)、みたいなノリになっています。
ちなみに、RFCを調べるときにはいつも Ajax RFC 検索 を使わせてもらっています。便利です。
ちょうど困ってたネタでした。ありがとう。
あとバッドノウハウならBKなのでは?
あはは、そうだ > BK
RFC に記述してあるとおり、ちゃんとした日付を指定してやればいいだけの話で、バッドノウハウでも何でもないと思いますが。規定されていないフォーマットを返したらブラウザによって解釈が変わるのはある意味当たり前。
ふーん。いつもながら勉強になります。