①ブラウザに一切、キャッシュさせたくない場合
サーバからクライアントへのHTTP応答ヘッダ
→ Cache-Control "no-cache"
アクセス毎に内容が変わったり、サーバにアクセスしてもらわないと困るようなコンコンテンツの場合です。
スクリプト言語等で生成する動的コンテンツは、このようにした方が安全です。
例えば対象コンテンツが画像である場合、ブラウザで同じ画像のURLが含まれたHTMLを開いた場合は、
- もちろんローカルにキャッシュがないので、サーバへ問い合わせを行う
- 条件つきリクエスト(If-Modified-Since、If-None-Match)もサーバへ送ってこない
②ブラウザにキャッシュさせるけど、変更ないか都度確認するようにしたい
サーバからクライアントへのHTTP応答ヘッダ
→ Cache-Control "max-age=0"
→ Expires "Mon, 26 Jul 1997 05:00:00 GMT"
ブラウザ毎に片方しかサポートしていない場合があるので、両方のヘッダを指定しておいた方がいいです。
最初から既に期限切れ、という意味です。
ブラウザで同じ画像のURLが含まれたHTMLを開いた場合は、
- 期限が切れてるので、サーバへ問い合わせを行う
- 条件つきリクエスト(If-Modified-Since、If-None-Match)をサーバへ送ってくる
ただし条件つきリクエストを送ってくるのは、前回にサーバから Last-Modified、Etag を送ってある場合のみです。
またサーバ側は、もし If-Modified-Since、If-None-Match がクライアントから送られてきたら、変更ありなしを判断して 304レスポンスを返せば通信量が減らせます(Apacheなど普通のWEBミドルウェアなら静的コンテンツの場合は勝手に処理してくれるでしょうけど)。
サーバから304レスポンスを受け取った場合、ブラウザはローカルのキャッシュを利用します。
③ブラウザにキャッシュさせ、都度確認はそれほど必要ない
上記②の時から次のように変更すればいいです。
サーバからクライアントへのHTTP応答ヘッダ
→ Cache-Control "max-age=秒数"
例:86400など(この場合は1日)
→ Expires "ここに期限の日時"
その期限に達していない限り、ブラウザはサーバに問い合わせを行いません。
期限がきれた後の挙動は、②と同じです。
補足
iPhoneやAndroid等のネィティブアプリ内のWebViewはキャッシュが強いので、サーバからのキャッシュコントロールに関わらず、ローカルのキャッシュが利用されることがあります(恐らくWebViewの設定でキャッシュポリシーを変更できるかとは思います)。