--- title: Facebook Pixel CodeとGoogle Chrome75の相性が良くない件について tags: JavaScript Chrome FacebookPixel author: neeton_iwasaki slide: false --- 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 ```js fbq('track', "PageView"); ``` を設定しているとおそらくクリックイベントあたりを判定してFacebookにGETあるいはPOSTでデータを送っているようです。POSTであってもFacebookに送信する際にはGETで送っていることもあったのですが、 ```js 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をしています。 ```js 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 ```
Alert dismissal bug tests. (Note: must reload the page after each button click.)


``` にあるように、 ``` setTimeout(function () { alert("Started slow cross-process navigation in iframe"); }, 0); ``` を呼ぶことで回避することができます。Facebook Pixel CodeのPOST処理は100ms程度でレスポンスが返ってくるようですので、500msくらい待てばバッテイングすることなくダイアログの表示ができました。