問題
<form>
をPOST
したあとで、遷移先のページから「戻る」ボタンで戻ると、フォームには送信したレコード(データ)が残っています。この状態で再度POST
すると、レコードが2重に登録されます(手抜きなコードなもので)。
この問題に対し、最初は「戻る」ボタンそのものを無効化しようとしました。Qiita の「ブラウザの戻るボタンを依存ライブラリ無しで戻れなくする方法」(2019年5月)や Stack Overflow の「How can I stop the browser back button using JavaScript?(回答は2015年12月)などにも、次のような、ブラウザ履歴を操作する解法が掲載されています。
history.pushState(null, null, null);
window.addEventListener('popstate', function (evt) {
history.pushState(null, null, null);
});
しかしこの手は、最近(2025年2月現在)は Firefox くらいでしか動かないようです。なんでもセキュリティ上の問題のせいらしいです。
解法
pageshow
イベントが発生したらフォームをリセットする。
説明
MDNの「Window: pageshow イベント」に依れば、このイベントは次のようなときに発火します。
- 最初にページを読み込んだとき
- 同じウィンドウまたはタブの中で、他のページからそのページへ移動してきたとき
- モバイル OS で凍結されたページを復元したとき
- ブラウザーの進む、戻るボタンを利用してこのページに戻ったとき
あとは、このイベントときにフォームをリセットします。<form id="order">
がターゲットのときの例を次に示します。
window.onpageshow = function() {
let elem = document.getElementById('order');
elem.reset();
};
おわりに
「戻る」をさせたくないのは基本設計がもともとしょぼいからです。ちゃんと設計し直せばよい、は王道ですが、まぁ、そこまで気力のないときもあります。