要約

  • 現行のNo-Vary-Search草案は、対応するキャッシュがレスポンスを照合するとき、指定されたクエリの違いを無視できるようにする。鮮度、認可、内容交渉を置き換えるものではなく、クライアント側の判断まで同じだと保証するものでもない。
  • Chromeの文書は、事前描画中に見えるURLと有効化後の最終URLを区別している。クエリ依存の状態はこの切り替わりで確定または更新する必要がある。アドレスバーが変わっても、データモデルや操作対象が変わった証拠にはならない。

商品一覧から二つの商品を開く場面を考えよう。サーバーが最初に返すHTMLは共通で、どちらの商品かはクエリに入った識別子を使って後から取得する。読者がクリックする前に、ブラウザーが一方のページを準備する。事前描画中のアプリケーションは最初の識別子を読み、その値をモデルに保存する。ところが読者が最後に選んだのは、もう一方の商品だった。

ブラウザーは準備済みの文書を再利用し、ページを有効化してURLを最終的な選択に変える。表示されるアドレスは正しい。しかし、アプリケーションの判断も変わっただろうか。

最初のHTMLが同じであることは、この問いへの答えにならない。モデルは準備時の商品を指したままかもしれない。訪問の計測や、利用者が後に実行する操作の対象も、古い値に結び付いている可能性がある。一度読み取った変数は、アドレスの更新だけで自動的に最新になるわけではない。これは設計上の境界を検討するための仮定であり、Chromeの不具合や実際の利用者被害を報告するものではない。

No-Vary-Searchが扱う同一性は、もっと狭い。あるクエリの違いによって別のサーバーレスポンスを取得する必要がない、という主張である。準備段階のURLから導いたすべての判断が、最終的な選択にも適切だという主張ではない。両方を「同じページ」で済ませると、キャッシュの最適化が、本来は決められない対象選択まで引き受けてしまう。

等価なのはレスポンスであり、読者の選択全体ではない

調査時点の最新文書は、HTTPBISの活動中のInternet-Draftであるdraft-ietf-httpbis-no-vary-search-09だ。2026年8月の本文は2027年2月18日に期限を迎える。Datatrackerは出版への提出と「Approved-announcement to be sent::AD Followup」の状態を示し、予定するRFCの区分はProposed Standardとなっている。承認手続きは進んでおり、承認のない個人提案として扱うのは正確でない。ただし本稿は、これを既に出版されたRFCとして扱わない。

提案されるフィールドはStructured Fieldsの辞書である。paramsは違いを無視できるパラメーター名を列挙する。exceptは逆に、列挙した名前を重要なまま残して、それ以外を無視する。両者は同時に指定できない。key-orderはパラメーター名の順序を考慮するかどうかを扱う。既知の項目を無効な形式で渡すと、既定の変動設定へ戻るのであって、すべてを無視してよい設定にはならない。

フィールドはURLから情報を消す命令ではない。キャッシュ照合に別の比較方法を加えるものだ。値を設定するのはオリジンであり、中継者はそのレスポンスのオリジンとして動作している場合を除き、挿入、削除、変更をしてはならない。キャッシュ自身の拡張対応も必要になる。ヘッダーが見つかったというだけで、すべてのブラウザー、CDN、フォワードプロキシに同じ実装があるとはいえない。

ほかのHTTP条件は残る。RFC 9111の保存可能性と鮮度、内容交渉やVaryを満たす必要がある。No-Vary-Searchで照合できたことは、個人向けレスポンスを別の利用者に渡す許可でも、無期限の再利用の根拠でもない。提供するレスポンスの意味に影響しないクエリの違いだけを、ほかのキャッシュ条件の中で扱う。

商品識別子は共通HTMLには不要でも、商品情報をサーバーで埋め込んだページには不可欠かもしれない。計測用に見えるパラメーターも、別のアプリケーションでは返す内容を変える。名前や分類から一律に判断するのではなく、実際に提供するレスポンスを確認する責任がオリジンにある。

先にレスポンスを取得することと、ページを動かすことを分ける

Chromeの公式文書は、有効化時の動きを具体的に説明している。No-Vary-Searchは、先行取得と事前描画のナビゲーション推測で利用できる。事前描画されたページは、まず準備に使われたURLを見る。最後にクリックされたURLが対象パラメーターだけ異なる場合、Chromeは準備済みページを使い、有効化時にURLを最終値へ置き換えられる。

そのため文書は、検索パラメーターに依存するJavaScriptを有効化後に実行するよう注意を促す。クライアントで描画する内容についても、有効化時の更新が必要になる場合がある。共通の初期HTMLと、後でクライアントが取得する異なる商品情報は両立する。この説明はChromeの文書に基づくもので、あらゆるブラウザーの対応を意味しない。

先行取得と事前描画を同じテストにまとめてはいけない。前者はレスポンスを前もって取得、準備する。後者は、実際のページとして見える前からコードを実行するページを準備し得る。古い識別子を先に保持する問題は、この後者のライフサイクルに関係する。先行取得なら必ずページのスクリプトが実行される、と一般化するのも誤りだ。

通常のナビゲーション、先行取得したレスポンスの再利用、事前描画からの有効化を別々に試す必要がある。最初から最終URLで開いたページが正しくても、準備URLから最終URLへ移る場合の証明にはならない。

推測ルールのexpects_no_vary_searchも、アプリケーションの正しさを認定しない。レスポンスにフィールドがあるという予想を表し、準備を効率化する助けになる。実際のオリジンの契約は別途成立していなければならない。予想どおりに取得できたことも、速く有効化できたことも、モデルやフォームの操作対象が正しい証拠ではない。

必要なのは明示的な引き継ぎである。予定したナビゲーションから導いた状態を暫定とし、有効化時に実際の選択を確認して、依存する状態を結び直す。見出しだけ更新して操作対象が古い商品に残っているなら、引き継ぎは完了していない。データを取得し直しても訪問の帰属が古いURLのままなら、それも別の未完了だ。

URLの変更は、状態の確定にも同意にもならない

有用な検査は、一つのクエリで準備し、別の等価なクエリで有効化する。その後、選ばれたレコード、見える内容、利用者の操作先を一緒に見る。アドレスバーだけでは、モデルや保持した変数に残る旧識別子が分からない。最終URLを一度読んだかではなく、その値が必要な判断に届いたかを確かめる。

これは早期処理の全面禁止ではない。共通の文書骨格、共有資産、本当にクエリに依存しない準備には価値がある。分けるべきなのは、早く準備することと、準備時の推測を読者の確定した選択として扱うことだ。選択肢を用意しても、その選択肢に後の行動を決める権限を与える必要はない。

有効化も一般的な許可ではない。どのナビゲーションが実際に使われたかを確定するだけで、認証、アクセス権、結果を伴う操作への同意を置き換えない。対象識別子を正しくすることは必要でも、それだけで何をしてもよいとはいえない。ページを開くことは、外部への情報提供や指示をすべて命じることではない。

サーバー側には、クライアントが後から補えない境界もある。版09は、安全な再利用に必要なサーバー処理を迂回するパラメーターをno-varyにしてはならないとする。例として認可、利用者識別、署名検証、同意、ルーティング、監査、失効を挙げる。適切な有効化処理でも、そもそも共有できないレスポンスや必要な処理を省いたレスポンスは救えない。

共有キャッシュで個人別の内容を選ぶパラメーターを誤って無視すれば、ある利用者のレスポンスが別の利用者へ渡る危険がある。レスポンスの等価性を確認する制御と、有効化後の判断を正しい対象へ結び付ける制御は補完関係にある。速さやHTMLの一致を、一方が他方を満たした証拠にしてはいけない。

クエリ比較には、文字列の印象ではなく定義が必要だ

草案はapplication/x-www-form-urlencodedの解析とWHATWGの規約を使う。URLから都合のよい部分文字列を取り除く処理ではない。既定の変動設定ではクエリそのものを比較する。既定以外の設定では、キーと値の組へ解析し、対象を絞り、必要ならキーによる安定した並べ替えを行って比較する。

エンコードや重複した値は否定的なテストに入れるべきだ。プラス記号とパーセント符号化は解析後の値に影響する。名前の順序を無視することは、同じ名前に付いた複数の値を自由に並べ替えることではない。Unicodeの正規化も行わない。草案は、不正なUTF-8の損失を伴う復号によって、異なるクエリが同じ結果になる危険も指摘する。安全性を、そのような不正列が解析後も区別できるという仮定に置くべきではない。

すべての解析例を経営判断に持ち込む必要はない。しかし最小限の契約には、正しい比較と意味のある境界テストが要る。各チームはレスポンスに応じて無視する項目を選べるが、キャッシュが用いる同一性を、見た目の似たURLという直感で置き換えることはできない。

パラメーターの意味は、古いレスポンスより先に変わり得る

有効化の境界には、リリースの境界も重なる。今日のHTMLには無関係なパラメーターが、次の版でサーバーやクライアントの判断に使われるかもしれない。少数の項目だけ残すexceptは、まだ知らない将来の項目も無視する。狭いparamsは、列挙されない項目を重要なまま残す。どちらも常に正しいわけではなく、将来の変更への責任の置き方が違う。

本稿は、パラメーターの意味、サーバー出力、クライアントの読み取り時点が変わるとき、等価性も再検討することを提案する。リリースと責任者を結び付け、古い保存レスポンスを新しいナビゲーションの意味に照らして試す。新しいレスポンスに新しいフィールドが付いたかだけでは足りない。これは著者のガバナンス上の提案であり、IETFが追加した必須フィールドではない。

オリジンの新しいヘッダーは、保存済みのすべてのオブジェクトを遡って書き換えない。草案は保存レスポンス自身の変動設定で照合し、新しい競合方針を優先するような戦略も認めるが、古い等価性が全域で直ちに消えるとは約束しない。また、失効要件は変更しない。概念的に等価なURIまで失効させることはできても、要求されるわけではない。

したがって、状態変更要求が通っただけでは、等価と考えるすべてのバリエーションの失効は証明できない。新しく取得させるためにクエリを変えても、保存方針がその項目を無視すれば効かない場合がある。移行には、利用するキャッシュに合う検証、失効処理、または区別できる資源の名前空間が必要だ。新しいクエリなら必ず新しい仕事になる、という一般論には頼れない。

最終選択が分かる場所へ、未来の判断を残す

heng.luの最小初期仕様、将来判断の局所化、自発的採用という考え方は、ここで契約の大きさを測る手掛かりになる。すべての商品選択を中央で決める必要はなく、有益な事前準備を禁じる必要もない。共有できる準備と、後で実際の選択に基づいて行う判断の境界を定めればよい。

オリジンはレスポンスについての狭い約束を守る。ブラウザーは有効化の引き継ぎを明示する。アプリケーションは、実際のナビゲーションが分かった時点でクエリ依存の判断を行い直す。「同じページ」に三者の責任をまとめて背負わせるのではなく、確認できる小さな契約として採用できるようにする。

プライバシー上の利点にも同じ節度が必要だ。草案は私有キャッシュの再利用によって追跡識別子の一部のオリジン処理を避けられると説明する。しかし共有キャッシュは識別子を含む要求を受け取り、フィールドはクライアント側の追跡を停止しない。再利用は匿名化ではなく、有効化は同意ではない。長く保てる約束は、等価なレスポンスを早く準備し、読者の本当の選択が分かったところで判断を結び付けることだ。

参考資料

  1. Datatracker:No-Vary-Searchの現行文書と出版状態。
  2. 草案の改訂履歴。
  3. 版09の保存文書:比較、キャッシュ、安全性。
  4. 版09のテキスト。
  5. 版09の構造化原文。
  6. HTTP Working Groupの拡張文書。
  7. HTTP拡張の議論記録。
  8. HTTPBISの活動範囲。
  9. RFC 9110:HTTPの意味論。
  10. RFC 9111:HTTPキャッシュ。
  11. RFC 9651:HTTPの構造化フィールド値。
  12. RFC 6943:識別子比較と安全性。
  13. WHATWG URL標準。
  14. WHATWG Infra標準。
  15. Chrome:事前描画とNo-Vary-Search有効化の注意点。
  16. heng.lu:最小仕様、局所的な将来判断、自発的採用。
  17. heng.lu:The Policy Mirror。