Как предотвратить блокировку всплывающего окна Google Chrome?

на моем сайте есть кнопка, которая просто используется для вызова функции, которая называет window.open, однако, недавно была необходима корректировка для проверки на стороне сервера до открытия всплывающего окна.

С тех пор, как был добавлен код, который выполняет вызов AJAX, браузеры блокируют всплывающее окно, которое открывается в success обратный вызов вызова AJAX. Я читал, что браузеры могут блокировать всплывающее окно, если оно не вызывается событием щелчка пользователя, поэтому я попытался установить запрос 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');

6 ответов


да, всплывающие окна должны быть прямым результатом действий пользователя. Выполнение их в обратном вызове ajax не сделает трюк. Кроме того, используя async:false плохо - в FF, как известно, блокирует весь браузер. Подумайте о другом способе сделать проверку:

  • это может быть первое, что вы делаете во всплывающем
  • вы можете открыть всплывающее окно по щелчку и управлять им позже, когда обратный вызов срабатывает
  • вы можете потребовать от пользователя снова нажать кнопку, чтобы вызвать всплывающее окно (вероятно, худшее решение)
  • вы можете сделать это на странице load

следуя отличному ответу Эмиля, "вы можете открыть всплывающее окно по щелчку и манипулировать им позже, когда обратный вызов срабатывает". Я использовал эту реализацию.

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

вы можете открыть окно, которое не заблокировано только под событием onclick,если вы откроете его при вызове ajax, оно считается всплывающим. Однако я использовал этот метод с успехом в течение некоторого времени, чтобы открыть всплывающее окно и не быть заблокированным.

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


в моем случае окна.open был запущен внутри обещания в angular, который включил блокировщик всплывающих окон, мое решение было:

$scope.gotClick = function(){

  var myNewTab = browserService.openNewTab();
  someService.getUrl().then(
    function(res){
      browserService.updateLocation(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 и не вызывая блокировщик всплывающих окон.


Предыдущее решение не работает для меня, но я на его основе и используемый им окно.

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

Я использую этот метод:

  1. перенаправление на ту же страницу с url-адресом загрузки, добавленным в качестве параметра:
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);
}