LoginSignup
11
4

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-07-25

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

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

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

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

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

理由

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

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()
                            });

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

2019/07/26追記

解決策

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

<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くらい待てばバッテイングすることなくダイアログの表示ができました。

11
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
4