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