ブラウザバック時のドキュメントのキャッシュ対策(no-storeを使わない方法)

ブラウザバック時のドキュメントのキャッシュ対策(no-storeを使わない方法)

Cache-control に「max-age=0, must-revalidate」と指定して ETag が一致していたら 304 レスポンスを返しているケースなどはよくあると思いますが、

ブラウザバックの場合ブラウザが保持しているページのリソースが disk cache などでそのまま読み込まれてしまう。

もちろん no-store を指定すれば常にサーバから最新のドキュメントを取得してくれるようになるのですが、

必要に応じてキャッシュを効かせたい場合には少々手当が面倒だし、これだけのためにキャッシュの指定を複雑に調整したくないのでフロントサイドでの対策を考えてみました。

pagehide イベントを使う

現在のページを非表示にする際に pagehide イベントが発火するので、その際にヒストリーにある URL を書き換えて Cache Busting を行う。

https://developer.mozilla.org/ja/docs/Web/API/Window/pagehide_event

// URL末尾にパラメータ付与
const addParam = (params = "", value = "", paramName = "t") => {
  params = params.split("&");
  const regex = new RegExp("^[?]?" + paramName + "=.*");
  params = params.filter((param) => {
    return !regex.test(param);
  });
  params = params.join("&");
  if (params.indexOf("?") !== -1) {
    params += `&${paramName}=` + value;
  } else {
    params += `?${paramName}=` + value;
  }
  return params;
};

// ページ遷移前
window.addEventListener("pagehide", () => {
  let params = window.location.search;
  const ver =
    new Date().getTime().toString(32).replace(/\./g, "") +
    Math.random().toString(32).slice(-8).replace(/\./g, "");
  params = addParam(params, ver, "t");
  window.history.replaceState(null, "", params);
});

このようにすれば画面遷移時にヒストリの URL が書き換えられるのでブラウザバックなどが行われた場合は別 URL として読み込みが行われる。

パラメータの't'や乱数の部分を好みのものに変えていけば他にも応用が効くはずです。

unload イベントでも同様のことが可能だと思います。