【问题标题】:Popup blocker triggered in onclick handler if there is a delay如果有延迟,则在 onclick 处理程序中触发弹出窗口阻止程序
【发布时间】:2020-07-16 14:35:27
【问题描述】:

在实施支付网关时,我遇到了一种情况,即最好将弹出窗口用于 3D 安全流程。

流程是这样的:

  1. 用户在支付页面上并在托管字段中输入信用卡数据。
  2. 在“购买”onclick 事件中,我调用网关的 javascript sn-p 来获取卡令牌。
  3. 我将其发布到后端。
  4. 后端检查是否需要 3DS。
  5. 如果是,前端会打开一个带有 3DS 表单的新窗口。

onclick 的代码如下:

var win;

$("#buy").click(function() {

    gateway.Tokenize(function(token) {

        $.ajax({
            url: 'backend.php',
            type: "POST",
            data: {
                token: token
            }
        }).done(function(data) {

            if (data.threeDRequired) {
                win = window.open(data.url, "_blank");
                win.focus();
            }

        });

    });

});

通常这没有问题,弹出窗口会打开,但如果 Tokenize 方法或 $.ajax 调用需要太长时间才能完成,则会触发弹出窗口阻止程序。即使在 $.ajax 调用中添加 async: false 也无济于事。

我能做些什么来让所有情况下都能正常工作吗?目前我能想到的唯一解决方案是在单击事件开始时打开一个弹出窗口,然后在可用时加载 URL,或者如果弹出窗口被阻止,则让用户单击其他按钮。 两者似乎都不理想。

【问题讨论】:

    标签: javascript jquery google-chrome popup popup-blocker


    【解决方案1】:

    事件是同步的并且会立即过期,这意味着您无法捕获点击并在将来的任何时间使用它的特权/权限。

    您可以做的是立即打开弹出窗口,然后在 Tokenize 返回后将其关闭或更新其位置。

    这是一种乐观的方法,但如果您确信成功是最值得期待的行为,那应该不会太烦人。

    var win;
    $("#buy").click(function() {
      win = window.open("about:blank", "_blank");
      gateway.Tokenize(function(token) {
        $.ajax({
          url: 'backend.php',
          type: "POST",
          data: {token: token}
        }).done(function(data) {
          if (data.threeDRequired) {
            win.location = data.url;
            win.focus();
          }
          else {
            win.close();
          }
        });
      });
    });
    

    这应该可以解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      • 1970-01-01
      • 2013-05-08
      相关资源
      最近更新 更多