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

发布于 2024-10-10 13:53:10 字数 1355 浏览 3 评论 0原文

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

自从添加执行 AJAX 调用的代码后,浏览器就会阻止在 AJAX 调用的 success 回调中打开的弹出窗口。我读到如果用户点击事件不调用浏览器可能会阻止弹出窗口,所以我尝试将 AJAX 请求设置为 async: false,这解决了 Firefox 中的问题,但 Google 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');

On my website there is a button that just used to call a function that calls window.open, however, recently an adjustment was needed to do a server-side check before the popup was opened.

Ever since the code was added that does the AJAX call, browsers blocks the popup, that is opened in the success callback of the AJAX call. I read that browsers might block the popup if it's not called by a user click event, so I tried setting the AJAX request to async: false, which solved the problem in Firefox, but Google Chrome still keeps blocking my popup. Is there any way to get around this?

I could move the server-side check to the page that gets opened in the popup, but I'd like to do it before opening the popup, if possible.

Code:

<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>

Example response body:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

忱杏 2024-10-17 13:53:10

是的,弹出窗口应该是用户操作的直接结果。在 ajax 回调中执行这些操作不会成功。另外,使用 async:false 是不好的 - 在 FF 中,众所周知它会阻塞整个浏览器。考虑其他一些方法来进行检查:

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

Yes, popups should be a direct result of a user action. Doing them in ajax callback will not do the trick. Also, using async:false is bad - in FF it is known to block the whole browser. Think of some other way to do the check:

  • it could be the first thing you do in the popup
  • you can open the popup on click and manipulate it later when the callback fires
  • you can require the user to click again some button to trigger the popup (probably the worst solution)
  • you can do it on page load
烟织青萝梦 2024-10-17 13:53:10

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

Following up on Emil's excellent answer, "you can open the popup on click and manipulate it later when the callback fires". I used this implementation.

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

New code here

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

end new code

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

    return false;
});
番薯 2024-10-17 13:53:10

您可以在 onclick 事件下打开一个不被阻止的窗口,如果您在 ajax 调用上打开它,则将其视为弹出窗口。然而,我使用这种方法成功了一段时间,打开了一个弹出窗口并且没有被阻止。

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

You can open a window that is not blocked just under the onclick event, if you open it on ajax call it is considered popup. However I used this method with success for some time to open a popup and not be blocked.

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

嗳卜坏 2024-10-17 13:53:10

这是一个普通的 JavaScript 解决方案,我正在使用一个我的网站,以绕过 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();
        });
});

Here is a vanilla JavaScript solution, I am using for one of my websites, to bypass the popup blocker in Chrome.

Let us say we have the following HTML button:

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

Now when the user clicks on the button, the first thing you should do is open an empty new window. After the Fetch request is finished, update the actual window URL. If the request fails, simply close the window:

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

半世晨晓 2024-10-17 13:53:10

就我而言,window.open 是在 Angular 的 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 响应而不调用弹出窗口阻止程序。

In my case the window.open was launched inside a promise in angular, which turned the popup blocker on, my solution was:

$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;
}

this is how you can open a new tab using the promise response and not invoking the popup blocker.

时光瘦了 2024-10-17 13:53:10

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

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

The previous solution did not work for me, but I based on it and used named window.

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();
        }
})
月朦胧 2024-10-17 13:53:10

我使用这种方法:

  1. 重定向到同一页面,并将下载网址添加为参数:
window.location.href = window.location.protocol + '//' +
                    window.location.host + window.location.pathname +
                    "?download=" + encodeURIComponent(urlToDownload)
  1. 在页面初始化时检测此参数并重定向到下载:
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);
}

I use this method:

  1. Redirect to the same page with download url added as parameter:
window.location.href = window.location.protocol + '//' +
                    window.location.host + window.location.pathname +
                    "?download=" + encodeURIComponent(urlToDownload)
  1. Detect this parameter on page initialization and redirect to download:
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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文