Cache-Control とブラウザ Back, Forward

ブラウザのキャッシュを抑制するヘッダとして,

  • Pragma: no-cache
  • Cache-Control: no-cache, no-store
  • Expires: 古い日付

が知られています。これらのヘッダを使った場合,

Page_A ←→ Page_B (no-cache) ←→ Page_C

という遷移において,各ページをブラウザの Forward, Back で移動したとき,Page_B は常に新しいコンテンツが読み込まれます…ただし,IE6 と Firefox 1.5 では。
(ちなみに,Cache-Control: no-cache だけだと Gecko 系ではうまくいきません)
Opera では,上記のような状態でも Page_B は(一時)キャッシュのものが用いられます。その根拠として,

Note that cache expiration is not checked when going back and forwards in the window history. It is only checked when you click a link. See RFC 2616, section 13.13.

と書かれています。

RFC の該当部分を引用すると

13.13 History Lists

User agents often have history mechanisms, such as "Back" buttons and history lists, which can be used to redisplay an entity retrieved earlier in a session.

History mechanisms and caches are different. In particular history mechanisms SHOULD NOT try to show a semantically transparent view of the current state of a resource. Rather, a history mechanism is meant to show exactly what the user saw at the time when the resource was retrieved.

By default, an expiration time does not apply to history mechanisms. If the entity is still in storage, a history mechanism SHOULD display it even if the entity has expired, unless the user has specifically configured the agent to refresh expired history documents.

This is not to be construed to prohibit the history mechanism from telling the user that a view might be stale.

Note: if history list mechanisms unnecessarily prevent users from viewing stale resources, this will tend to force service authors to avoid using HTTP expiration controls and cache controls when they would otherwise like to. Service authors may consider it important that users not be presented with error messages or warning messages when they use navigation controls (such as BACK) to view previously fetched resources. Even though sometimes such resources ought not to cached, or ought to expire quickly, user interface considerations may force service authors to resort to other means of preventing caching (e.g. "once-only" URLs) in order not to suffer the effects of improperly functioning history mechanisms.

むべなるかなという感じですが,

If the entity is still in storage, a history mechanism SHOULD display it even if the entity has expired, unless the user has specifically configured the agent to refresh expired history documents.

太字強調した部分が逆に Firefox での挙動を保証している気がしました(no-store なんだから保存してないもんね,と)。

この辺の話は,PHP-users mailing list のこのスレッドが参考になりました。