「ページの有効期限切れ」をsession_cache_limiter()で解決

今日、学んだことの自分用メモです。
主に下記のリンク先を参照してまとめたものです。
http://www.glamenv-septzen.net/pukiwiki/index.php?PHP%2F%A1%D6%A5%DA%A1%BC%A5%B8%A4%CE%CD%AD%B8%FA%B4%FC%B8%C2%C0%DA%A4%EC%A1%D7%C2%D0%BA%F6
文章がカブってたりしますが、その辺はお許し下さい。・△・

概要

「ページの有効期限切れ」という画面を表示しないようにする。
解決策としてsession_cache_limiter()関数を利用してページがキャッシュされるように設定する。
session_cache_limiter()はカレント(現在表示しているWebページ)のクライアントに送信されるキャッシュ制御用HTTPヘッダの設定が行える。

キャッシュ制御ヘッダについて

キャッシュ制御用HTTPヘッダは以下のようなもの。

  • HTTP/1.0のキャッシュ制御ヘッダフィールド
    • Expires(いつ無効になるかを示す)
    • Pragma(キャッシュの許可を示す)
  • HTTP/1.1のキャッシュ制御ヘッダフィールド
    • Cache-Control(キャッシュ制御)
    • Last-Modified(最終更新日)

Expires,Pragmaは下位互換性のため現在も使用されてるが、HTTP/1.1に対応したプログラムの場合はCache-Controlがこれより優先される。

キャッシュされる場所について

Webページがキャッシュされる場所は以下の二ヶ所ある。

  • クライアントPC
  • プロキシサーバ

プロキシは一般に共用サーバなので、「個人情報やプライバシーに関わる入力フォームの内容はキャッシュするべきではない」ということになる。よって、(その他の諸理由も含めて)入力フォームのある画面では「キャッシュ不可とすべき」というRFC*1の定義があるらしい。*2

「有効期限切れ」画面の原因

以上のことから「ページの有効期限切れ」画面が表示される原因は、HTTPヘッダのキャッシュ制御フィールドにおいてキャッシュ不可を指示されたからであると言える。

つまり、IEのこの画面はバグではなくRFCに従った正常な動作であり、Firefoxの場合もキャッシュがないため再度リクエストを送っているだけなのでRFCから逸脱していない。

モードの種類

session_cache_limiter()関数に設定できるキャッシュ制御モードは以下の4種類がある。

nocache クライアント/プロキシのキャッシュを許可しない
public クライアント/プロキシのキャッシュを許可する
private クライアントのキャッシュを許可し、プロキシのキャッシュを許可しない
private_no_expire 機能はprivateと同じだが、Mozilla系を混乱させないためExpiresヘッダを送信しない

注意点

キャッシュ許可をする場合、次のことに気をつける。

  • 入力フォームによって再POSTされてしまいDBとの整合性を保てなくなる。

この場合の対策として、ユニークなキー値をその都度生成し、hiddenとしてフォームに埋め込んでおく「チケット」を導入することが考えられる。

まとめ

session_cache_limiter('private_no_expire');

の一文をスクリプトに追加することで、「有効期限切れ」画面の表示を回避できる。・▽・

*1:http://www.studyinghttp.net/cgi-bin/rfc.cgi?2616

*2:詳細はまだ調査中、難しくてよく理解できない・△・