如何阻止Google Chrome阻止我的弹出窗口?

时间:2011-01-05 10:21:27

标签: javascript google-chrome popup popup-blocker

在我的网站上有一个按钮,用于调用调用window.open的函数,但是,最近需要在弹出窗口打开之前进行服务器端检查。

自从添加了执行AJAX调用的代码以来,浏览器会阻止弹出窗口,该弹出窗口是在AJAX调用的success回调中打开的。我读过,如果没有用户点击事件调用,浏览器可能会阻止弹出窗口,所以我尝试将AJAX请求设置为async: false,这解决了Firefox中的问题,但谷歌Chrome仍然阻止弹出窗口。有没有办法解决这个问题?

我可以将服务器端检查移动到弹出窗口中打开的页面,但是如果可能的话,我想在打开弹出窗口之前执行此操作。

代码:

<a id="attackButton" href="#">Attack Base!</a>

<script type="text/javascript">
$(function() {
    $('#attackButton').click(function() {
        $.ajax({
            url: baseurl + '/index.php?option=com_pbbgs&format=raw&getinfo=goingame',
            data: { 'gameid': 618 },
            dataType: 'text',
            async: false,
            type: 'POST',
            success: function(data) {
                eval(data);

                if (window.gameURL) {
                    goingameRaw();
                }
            }
        });

        return false;
    });
});

function goingameRaw()
{
    window.open(window.gameURL,'test','left=20,top=20,width=1024,height=640,toolbar=0,resizable=0,location=0');
}
</script>

示例响应正文:

window.gameURL="http://mydomain.com/index.php?option=com_pbbgs&format=raw&startgame=618&width=1024&height=640";checktutorial('js','attack');

7 个答案:

答案 0 :(得分:46)

是的,弹出窗口应该是用户操作的直接结果。在ajax回调中执行它们不会起作用。此外,使用async:false是不好的 - 在FF中,已知会阻止整个浏览器。想一想其他方法来做检查:

  • 这可能是你在弹出窗口中做的第一件事
  • 您可以在点击时打开弹出窗口,稍后在回调触发时进行操作
  • 您可以要求用户再次单击某个按钮以触发弹出窗口(可能是最差的解决方案)
  • 您可以在页面加载
  • 上执行此操作

答案 1 :(得分:20)

跟进Emil的优秀答案,“你可以点击弹出窗口,稍后在回调触发时操纵它”。我使用了这个实现。

$('#attackButton').click(function() {

此处的新代码

    var win = window.open('');
    window.oldOpen = window.open;
    window.open = function(url) { // reassignment function
        win.location = url;
        window.open = oldOpen;
        win.focus();
    }

结束新代码

    $.ajax({
        url: baseurl + '/index.php',
        data: { 'gameid': 618 },
        type: 'POST',
        success: function(data) {
            window.open('some url'); // will call reassignment function above 
        }
    });

    return false;
});

答案 2 :(得分:5)

您可以在onclick事件下打开一个未被阻止的窗口,如果您在ajax调用中打开它,则会将其视为弹出窗口。但是我使用这种方法成功了一段时间才打开弹出窗口而不被阻止。

http://en.nisi.ro/blog/development/javascript/open-new-window-window-open-seen-chrome-popup/

答案 3 :(得分:2)

在我的情况下,window.open是在角度promise内启动的,这打开了弹出窗口阻止程序,我的解决方案是:

$scope.gotClick = function(){

  var myNewTab = browserService.openNewTab();
  someService.getUrl().then(
    function(res){
      browserService. updateTabLocation(res.url, myNewTab);
    }
  );
};

browserService:

this.openNewTab = function(){
  var newTabWindow = $window.open();
  return newTabWindow;
}

this.updateTabLocation = function(tabLocation, tab) {
  if(!tabLocation){
    tab.close();
  }
  tab.location.href = tabLocation;
}

这是您使用promise响应打开新标签而不是调用弹出窗口拦截器的方法。

答案 4 :(得分:1)

这是我的网站之一,使用的是普通JavaScript solution,可绕过Chrome中的弹出窗口阻止程序。

让我们说我们有以下HTML按钮:

<button id="clickMe">Click Me!</button>

现在,当用户单击按钮时,您应该做的第一件事是打开一个空的新窗口。 Fetch请求完成后,更新实际的窗口URL。如果请求失败,只需关闭窗口:

const button = document.querySelector('#clickMe');

// add click event listener
button.addEventListener('click', () => {

    // open an empty window
    const tab = window.open('about:blank');

    // make an API call
    fetch('https://reqres.in/api/users')
        .then(res => res.json())
        .then(json => {

            // TODO: do something with JSON response

            // update the actual URL
            tab.location = 'https://attacomsian.com';
            tab.focus();
        })
        .catch(err => {
            // close the empty window
            tab.close();
        });
});

答案 5 :(得分:0)

之前的解决方案对我不起作用,但我基于它并使用了命名窗口。

internalCounter++;
var tabbedWin = window.open('','windowName_'+internalCounter);
$.ajax({
        url: url,
        async: false,
        indexValue:internalCounter,
        success: function(){
            var w= window.open(url, 'windowName_'+this.indexValue);                
            w.focus();
        }
})

答案 6 :(得分:0)

我使用这种方法:

  1. 重定向到同一页面,并将下载网址添加为参数:
  2. window.location.href = window.location.protocol + '//' +
                        window.location.host + window.location.pathname +
                        "?download=" + encodeURIComponent(urlToDownload)
    
    1. 在页面初始化时检测此参数并重定向下载:
    2. function param(name){
          var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
          if (!results) { return 0; }
          return results[1] || 0;
      }
      
      var downloadParam = param('download');
      if (downloadParam) {
          window.location = decodeURIComponent(downloadParam);
      }