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

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

2022-10-21

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イベントでも同様のことが可能だと思います。