はじめに
フロント側のみでリロード対策をしなければならないときがありました
できればユーザーにリロードをさせないようにしたいのですが、完全にリロードを禁止するというのは無理そうかつ、こういったユーザーの行動を制限するのもあまりよくないみたい
とりあえず今回は、
- 幸い保持しておきたいデータが漏れても大丈夫なレベル
- データ量も少ない
という理由から localStorage sessionStorageで情報を保持することで対策しようと思いました。
sessionStorageでリロード対策
全体の流れとしては、
- ページ読み込み時にリロードしたのかの判定
- リロード判定が必要な処理内でリロードの場合とそうでない場合で処理わける
- リロードじゃない場合:ローカルストレージにデータ保存
- リロードの場合ローカルストレージからデータ取得
まずはリロードの判定について、
let isReload = false
window.addEventListener('load', () => {
const perfEntries = performance.getEntriesByType("navigation")
isReload = perfEntries[0].type === 'reload'
})
getEntriesByType
を使ってnavigation
オブジェクトを取得し、読み込みタイプを取得します。
navigate
、reload
、back_forward
、prerender
のいずれかが返ってくるので、その値に応じてisReload
を更新します。
そして、addEventListener
のload
イベントを用いて、ページ読み込み時のみリロード判定の処理を実行させます。
続いて、リロード判定が必要な関数内に処理をかきます。
let key = null
async function sample() {
// 他の処理
// ~~~~
// ~~~~
if(isReload){
key = sessionStorage.getItem('key')
sessionStorage.removeItem('key')
isReload = false
}
// key返す処理
// リロードあった場合は別の値が返ってくるが、前の値と紐づけておきたいのでリロード前の値が必要
key = await getKey(key)
if(!sessionStorage.getItem('key')) {
sessionStorage.setItem('key', key)
}
// 他の処理
// ~~~~
// ~~~~
}
リロードから読み込まれた場合は、ローカルストレージから保存しておいたデータを取得。
リロードじゃない場合かつ、ローカルストレージの任意のキーに値が保存されていない場合は値をセット。
最後に
リロード対策についていろいろと情報があると思うのですが、他にいい方法があればご教示いただけたら嬉しいです