初めに
ブラウザバックされないようにpostate
で検知して処理をしようしているのに、検知する時としない時の違いがわからず苦戦しました。
今回はその原因究明と解決策をまとめておきます。
ChromeやAndroidWebViewではpopstateは動かない
厳密にはクリックやタップなどのユーザーアクションが実行されない限り、popstatは動きません。
これはセキュリティ観点の問題であり、Chrome はデフォルトの「戻る」ボタン動作のハイジャックを意図的に防止しているからです(こちらで言及されています)
vue3で困ったこと
VueアプリケーションはSPAであり、vue内で何度パスが変わっても単一ページとして一回でもユーザーがクリックすれば、その後の popstateは検知してくれました。
しかし、外部サイトから遷移したときに、外部サイトに戻れないようにするためにpopstateでブラウザバックを検知させようとしても、今までのクリックイベントはリセットされてしまうので、再度クリックしないと検知してくれません。
なので、外部サイトから遷移してきたユーザーが、クリックせずにブラウザバックすると戻れてしまうのでとても困りました。
解決策を考えてみた
外部サイトと遷移先ページの間にダミーページを挟み、外部サイトから遷移したダミーページでHistoryAPIのpushを使って、目的のページに遷移させようとしました。そうすることでブラウザバックしても、いったんはダミーページを挟むので、そこで何かしらの処理をしようと考えました。
しかしこの方法は解決に繋がりません。
なぜなら、JSのHistoryAPIを用いて履歴操作された追加ページも、その間ユーザーがクリックしていなければ、ブラウザバックしても無視されてしまうからです。(aページ→bページ(ここでcページにpush)→cページ→ブラウザバックするとaページへ遷移)※1
vue-routerも内部的にはHistoryAPIに依存しているんですね。※2
※1 ※2
解決策
alertや戻るボタンを独自で作って、ユーザにクリックを促すようにするしかない。です笑