javascript Angularjs $window.open 弹出窗口被阻止

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19485594/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 15:44:45  来源:igfitidea点击:

Angularjs $window.open popups being blocked

javascriptangularjsbrowserpopup

提问by giodamelio

I am trying to use the Github API's web auth flowfrom within an AngularJS app. When my signup form submits, I want to open a new window to send them to the the auth page. Normally I would just use window.openinside a user event to ensure it wouldn't get caught by a popup blocker.

我正在尝试从 AngularJS 应用程序中使用 Github API 的网络身份验证流程。当我的注册表单提交时,我想打开一个新窗口将它们发送到身份验证页面。通常我只会window.open在用户事件中使用以确保它不会被弹出窗口阻止程序捕获。

In my angular app, I am wrapping a bit of the Github api in and Angular service, and the code to open the window goes in there. Because of that it gets blocked. I also tried putting it in a function in the controller that gets called by a form via ng-submit.

在我的 angular 应用程序中,我将一些 Github api 包装在 Angular 服务中,并且打开窗口的代码在那里。正因为如此,它被阻止了。我还尝试将它放在控制器中的一个函数中,该函数通过ng-submit.

So the question is, is there an elegant way to open a new page on a form submit from somewhere inside my service or controller, or will I need to find another way to do it?

所以问题是,是否有一种优雅的方式可以在从我的服务或控制器内部的某个地方提交的表单上打开一个新页面,或者我是否需要找到另一种方式来做到这一点?

回答by Nirav Gandhi

Chrome by default blocks popups that are not a result of user's direct action. In your case, I assume, the call to window.open is made inside a callback function. This makes it asynchronous and Chrome blocks it.

默认情况下,Chrome 会阻止不是用户直接操作导致的弹出窗口。在您的情况下,我假设对 window.open 的调用是在回调函数中进行的。这使它成为异步的,Chrome 会阻止它。

//before
$scope.userClicked = function(){
  $http.post('your/api/endpoint',{data:x}).then(function(r){
    $window.open(r.data.url,'window name','width=800,height=600,menubar=0,toolbar=0');
  });
}

However, there is a workaround to make this work. Instantiate your window outside the callback function and you can reference the variable to change the target url of that window in callback function.

但是,有一种解决方法可以使此工作正常进行。在回调函数之外实例化您的窗口,您可以引用该变量以在回调函数中更改该窗口的目标 url。

//after
$scope.userClicked = function(){
  var popup = $window.open('','window name','width=800,height=600,menubar=0,toolbar=0');
  popup.document.write('loading ...');

  $http.post('your/api/endpoint',{data:x}).then(function(r){
    popup.location.href = r.data.url;
  });
}

回答by Mahbub

You can't get rid of the popup blocker for scripted automated window.open. Only real user's call to action events will open a new window without being blocked by popup blocker. Imagine a situation in a site where there's no popup blocker in browser and javascript opens 100 popups in a loop. Would you like it ? It used to be there in our old good times like a virus but modern browsers are much smart and this annoyance is handled gracefully.

您无法摆脱脚本化自动 window.open 的弹出窗口阻止程序。只有真实用户的号召性用语事件才会打开一个新窗口,而不会被弹出窗口阻止程序阻止。想象一下在浏览器中没有弹出窗口阻止程序并且 javascript 循环打开 100 个弹出窗口的站点中的情况。你喜欢吗?它曾经在我们过去的美好时光中像病毒一样存在,但现代浏览器非常聪明,并且可以优雅地处理这种烦恼。

回答by basarat

You could quite simply create a directive to do this from within a clickevent content:

您可以很简单地创建一个指令来从click事件内容中执行此操作:

yourapp.directive('awesomeClick', ['$parse',function ($parse): ng.IDirective {
    return {
        restrict: 'A',        
        link: (scope, element:JQuery, attrs) => {
            var fn = $parse(attrs.awesomeClick);
            element.on('click', function (event) {

                // open the window if you want here 

                scope.$apply(function () {
                    fn(scope, { $event: event });
                });
            });
        }
    }
}]);