Help us understand the problem. What is going on with this article?

Facebook Pixel CodeとGoogle Chrome75の相性が良くない件について

Google Chrome75 でフォームの alert や prompt が勝手に閉じてしまうというバグが報告されています。

https://bugs.chromium.org/p/chromium/issues/detail?id=972456

削除系の処理などだとフォームのボタンをクリックした際に confirm を表示して「OK」をクリックしたあとでsubmitが発動するケースもあるかと思いますが、それが正常に処理されなくなるという不具合です。

この問題が発生するケース

  • formのPOST時にconfirmを表示してからSubmitしている
  • Facebook Pixel Codeを導入している(iframeでのPOSTが実行される)
  • formのPOST時のQueryStringが2048文字以上である

Facebook Pixel Codeが原因で発生する件については以下でも言及されています。

https://bugs.chromium.org/p/chromium/issues/detail?id=972456#c10

理由

Facebook Pixel Codeのタグを見てみましょう。

https://connect.facebook.net/en_US/fbevents.js

fbq('track', "PageView");

を設定しているとおそらくクリックイベントあたりを判定してFacebookにGETあるいはPOSTでデータを送っているようです。POSTであってもFacebookに送信する際にはGETで送っていることもあったのですが、

                    c = function c() {
                        var f = this;
                        l(this, c);
                        this.sendGET = function(b, c, d) {
                            b.replaceEntry("rqm", "GET");
                            var g = b.toQueryString();
                            g = e(c, d) + "?" + g;
                            if (g.length < 2048) {
                                var h = new Image();
                                if (d != null) {
                                    var i = a.getShouldProxy();
                                    h.onerror = function() {
                                        a.setShouldProxy(!0),
                                        i || f.sendGET(b, c, d)
                                    }
                                }
                                h.src = g;
                                return !0
                            }
                            return !1
                        }
                        ;
                        this.sendPOST = function(a, c, d) {
                            var e = b.get("xhr_cors_post");
                            if (e) {
                                a.append("exp", e.code);
                                if (e.isInExperimentGroup)
                                    return f._sendXHRPost(a, c, d)
                            }
                            return f._sendFormPOST(a, c, d)
                        }
                        ;

にあるように、 toQueryString が 2048より短ければGETでリクエストが送信されます。

次にPOST時の動きを見てみます。iframeを作成してその中でPOSTをしています。

                        this._sendFormPOST = function(c, i, j) {
                            c.replaceEntry("rqm", "formPOST");
                            var k = b.get("set_timeout_post");
                            k && c.append("exp", k.code);
                            var l = "fb" + Math.random().toString().replace(".", "")
                              , m = h.createElement("form");
                            m.method = "post";
                            m.action = e(i, j);
                            m.target = l;
                            m.acceptCharset = "utf-8";
                            m.style.display = "none";
                            var n = !!(g.attachEvent && !g.addEventListener)
                              , o = h.createElement("iframe");
                            n && (o.name = l);
                            o.src = "about:blank";
                            o.id = l;
                            o.name = l;
                            m.appendChild(o);
                            d(o, "load", function() {
                                c.each(function(a, b) {
                                    var c = h.createElement("input");
                                    c.name = decodeURIComponent(a);
                                    c.value = b;
                                    m.appendChild(c)
                                }),
                                d(o, "load", function() {
                                    m.parentNode && m.parentNode.removeChild(m)
                                }),
                                k && k.isInExperimentGroup && c.get("ev") === "SubscribedButtonClick" ? setTimeout(function() {
                                    return m.submit()
                                }) : m.submit()
                            });

https://bugs.chromium.org/p/chromium/issues/detail?id=972456#c35

で言及されているようにiframeにおけるPOST時の動作について次期バージョンでは修正がされているようです。

2019/07/26追記

解決策

setTimeoutを使ってconfirmの実行を遅延させます。つまり、Facebook Pixel CodeのPOST処理を実行後に本来行いたいFORMのPOSTを実行するようにします。

https://bugs.chromium.org/p/chromium/issues/attachmentText?aid=401097

<html>
<head>
<script>
function submitAndAlert() {
  document.getElementById("form1").submit();
  alert("Form submitted");
}
function slowNavAndAlert() {
  frames[0].location.href = "http://tests.netsekure.org/slow.php?seconds=1";
  setTimeout(function () { alert("Started slow cross-process navigation in iframe"); }, 0);
}
</script>
</head>
<body>
<iframe name="frame1"></iframe>
<form id="form1" action="http://csreis.github.io" target="frame1">
</form>
Alert dismissal bug tests.  (Note: must reload the page after each button click.)<br>
<button onclick="submitAndAlert()">Submit form and alert (affects M75+)</button><br>
<button onclick="slowNavAndAlert()">Start slow navigation and alert (affects M67+)</button><br>
</body>
</html>

にあるように、

setTimeout(function () { alert("Started slow cross-process navigation in iframe"); }, 0);

を呼ぶことで回避することができます。Facebook Pixel CodeのPOST処理は100ms程度でレスポンスが返ってくるようですので、500msくらい待てばバッテイングすることなくダイアログの表示ができました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした