Cache-Controlのno-cacheとno-storeは更新確認と保存禁止を分けて使う
公開日: 執筆:佐藤
Cache-Control: no-cacheとCache-Control: no-storeは同じ指定ではありません。no-cacheは、保存されているresponseを使う前にorigin serverへ確認するよう求めます。no-storeは、requestとresponseを保存しないよう求めます。CSSやJavaScriptを更新したのに古い表示が残る問題と、個人情報を保存させたくない問題では、先に解決したいことが違います。
cacheが関わる問題では、「古いものが残っている」とだけ考えると対処を誤ります。公開pageを速く表示するために保存を利用したい場合と、ログイン後の内容を保存されたくない場合は、正反対の条件を持つことがあります。どのresponseを、誰のbrowserまたは途中のcacheで、どのくらい使わせるかを分けて考えます。
RFC 7234は、Cache-Controlをrequestとresponseの経路にあるcacheへdirectiveを渡すHTTP header fieldとして定義しています。responseのno-cacheは、origin serverでのsuccessful validationなしに後続requestへresponseを使わないよう求めます。responseのno-storeは、immediate requestまたはresponseのどの部分も保存しないよう求めます。RFCは、no-storeがprivacyを保証する十分な仕組みではないことも説明しています。
更新を確かめることと保存を止めることを分ける
pageの内容が更新されたとき、古い表示を使う前にserverへ確認させたいなら、論点はno-cacheです。login後の画面や個人情報を含むresponseを保存させたくないなら、論点はno-storeです。
| 確認したいこと | 考えるdirective | 追加で確認すること |
|---|---|---|
| 保存済みresponseを使う前に最新か確認したい | no-cache |
response headerが実際に返っているか |
| requestやresponseを保存させたくない | no-store |
privateな情報をURLやHTMLへ含めていないか |
| 一定時間は新しいresponseとして使いたい | max-age |
更新時にversionをどう替えるか |
| browserとproxyで同じ表示を確認したい | header全体 | server、CDN、applicationのどこがheaderを出すか |
no-cacheという名前から、cacheへ一切保存しない指定だと思いやすいですが、RFCの意味は「保存済みresponseを検証なしに使わない」です。更新確認のためにno-storeを一律で付けると、表示速度や通信量へ影響する場合があります。反対に、no-cacheだけでprivateな情報を保存しないことを保証するものでもありません。
公開されている画像、CSS、JavaScriptのように、同じ内容を多くの人へ配るresourceでは、保存を活用する理由があります。一方、利用者ごとに内容が変わる画面では、別の人へ同じresponseを渡してはいけないことがあります。pageの種類を分けずに、site全体へ同じdirectiveを付けると、どちらかの目的を損ないます。まず、公開情報のresourceと、利用者ごとの情報を含むresponseを一覧にします。
server、application、proxy、CDNなど、responseへ関わる場所が複数ある場合は、どこが最終的なheaderを出しているかも確認します。applicationの設定だけを見ていても、途中の設定でheaderが替わっているかもしれません。担当者が違うときは、対象URL、返るheader、変更する場所を同じメモに残します。header名だけを伝えて、誰かがどこかで設定する状態を避けます。
CSSやJavaScriptの更新はfile名とresponseを一緒に確認する
stylesheetやscriptを更新したのに表示が変わらない場合、HTML、CSS file、JavaScript file、browser cache、proxy cacheのどこに古いdataがあるかを分けます。headerだけを替える前に、実際に読まれているURLを確認します。
- 変更したpageとstatic fileのURLを記録する。
- browserのnetwork情報で、HTMLとstatic fileのresponse headerを確認する。
- 同じURLへ古いfileが返るのか、HTMLが古いfile URLを指しているのかを分ける。
- file更新の方法とCache-Controlの設定場所を確認する。
- browserを替えるかprivate windowで再確認し、変更日と結果を残す。
CSSのURLへversionを付ける方法は、更新したfileを別のresourceとして扱わせる手段です。Cache-Controlを替えることと、HTMLがどのfile URLを読むかを替えることは別の作業です。どちらを行ったかを記録しなければ、次の更新で同じ問題を調べ直すことになります。
具体的には、公開pageを開いてHTMLを確認し、そのHTMLが指しているCSSとJavaScriptのURLを確認します。次に、そのURLを直接確認してresponse headerと内容を見ます。HTMLが新しいURLを指していなければ、CSS fileだけを更新しても画面は変わりません。HTMLが新しいURLを指しているのに古い内容が返るなら、fileの配置またはcacheの設定を調べます。問題の場所を分ければ、すべてのheaderを強くする必要はありません。
更新後の確認を一人のbrowserだけで終えると、前回の表示状態に引きずられることがあります。private windowや別のbrowserで同じURLを開き、必要なら別の端末でも確認します。ただし、そこで表示が違っただけで原因を決めません。各確認でどのURLを開き、どのresponse headerを見たかを残します。再現できる記録があれば、server担当へ渡す情報も明確になります。
privateな画面はcache以外の情報も確認する
no-storeは保存を避けるためのdirectiveですが、privacyを保証する仕組みではありません。URLに個人情報や認証用の値を含める、共有端末でloginを残す、メールでprivate URLを送るといった問題は、response headerだけでは解決しません。
ログイン後の画面を確認するときは、利用者ごとに内容が変わる箇所を見ます。氏名、住所、申込内容、管理画面のような情報がHTML、URL、画面内のlink先へ残らないかを確かめます。logout後に戻る操作をしたときの画面も、対象siteで確認します。cache headerはその確認の一部であり、認証や公開範囲を決める作業全体の代わりではありません。
cacheの設定を外部のserver担当へ任せる場合も、どのpageが公開情報か、どのpageがlogin後の情報か、更新を誰が確認するかはsite側で整理します。設定作業と、情報を公開してよいか判断する作業を分けます。最初に一つのURLを選び、目的、返すheader、更新後に見る場所を対応させれば、no-cacheとno-storeを名前だけで選ばずに済みます。
関連記事

