2019-12-29に投稿

Google Chromeではhistory APIを使った戻るボタンの制御ができない

タイトルの通り、Chromeではhistory APIを使った戻るボタンの制御ができません。
History APIを使って、戻るボタンを使えなくしたり、戻るボタンを押したタイミングでモーダルを表示させたりできるんですが、それがChromeではできません。

$(function(){
    history.pushState(null, null, "#popup");

    $(window).on("popstate", function(eve){
        if (location.hash == "") {
            // ハッシュが空になったら = ブラウザバックされたら
            $('.js-modal').show();
        }
    });
});

例えばこんなコードがあったとすると、SafariやIEでは動きますがChromeでは動きません。
似たような手法でHistory APIを使わずに直接ハッシュをいじる手法もあるんですが同じく動きません。

なんでだろうと思ってネット上をさまよってたんですが、結果こんな記事を見つけました。

https://www.zdnet.com/article/google-working-on-blocking-back-button-hijacking-in-chrome/

Google engineers are currently working on a Chrome browser update that will block malicious
websites from hijacking the browser’s history and, indirectly, the Back button.

ざっくり言うとHistory APIを使って戻るボタンを制御して悪いことをやるサイトが多いので、その手法をブロックしようとしていると言うことですね。(英語ほぼ読めないので適当ですが、そんなに間違ってないかと)
この記事が書かれたのが去年の12月なので、もうすでにブロック機能が追加されていると言うことなんだと思います。

ちなみにHacker Newsにもスレッドが立っていました。

https://news.ycombinator.com/item?id=18711452

このブロックの抜け道を探してみましたが見つかっていません。リンクに仕込まれたHistory APIだったら動作するだろうと思い、リンクにHistory APIを仕込んでclickイベントをJSで発火させてみたりしましたが動作しませんでした。
さすがGoogleと言うことで、おそらくそんなに簡単に突破できないかなと。

もし突破する方法を知っている方がいましたら、コメント欄などで教えていただけると助かります。

追記

chromeの仕様を詳細に書くと、「ページ読み込み直後に、ブラウザバックでのpopstateイベントが発火しない」ということみたいです。
ユーザーがクリックなどの能動的なアクションを一度でも起こした後であれば発火します。
なので、ページに飛んできたユーザーに一番最初にボタンを押してもらうようなUIを作れればこの問題は回避できるかもしれません。

Originally published at 11-30am.com
ツイッターでシェア
みんなに共有、忘れないようにメモ

takuhito-h

フリーランスでフロントエンドエンジニアをやっています。 こちらには個人ブログの中から、質の高めな技術記事を転載しています。

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント