简体   繁体   English

AngularJS $ window.open弹出窗口被阻止

[英]Angularjs $window.open popups being blocked

I am trying to use the Github API's web auth flow from within an AngularJS app. 我正在尝试从AngularJS应用程序中使用Github API的网络身份验证流程 When my signup form submits, I want to open a new window to send them to the the auth page. 当我的注册表单提交后,我想打开一个新窗口将其发送到auth页面。 Normally I would just use window.open inside a user event to ensure it wouldn't get caught by a popup blocker. 通常,我只会在用户事件内使用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. 在我的angular应用程序中,我在Angular服务中包装了一些Github api,打开窗口的代码就在其中。 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 . 我还尝试将其放在控制器中的函数中,该函数通过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? 因此,问题是,是否有一种优雅的方法可以从服务或控制器内部的某个位置在提交的表单上打开新页面,还是我需要寻找另一种方法?

Chrome by default blocks popups that are not a result of user's direct action. 默认情况下,Chrome会阻止不是用户直接操作导致的弹出窗口。 In your case, I assume, the call to window.open is made inside a callback function. 在您的情况下,我假设对window.open的调用是在回调函数中进行的。 This makes it asynchronous and Chrome blocks it. 这使它异步,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;
  });
}

You can't get rid of the popup blocker for scripted automated window.open. 您无法摆脱脚本化自动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. 想象一下一个站点的情况,该站点的浏览器中没有弹出窗口阻止程序,而javascript会循环打开100个弹出窗口。 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. 它曾经像病毒一样在我们过去的美好时光中存在过,但是现代的浏览器却非常聪明,这种烦恼得到了很好的处理。

You could quite simply create a directive to do this from within a click event 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 });
                });
            });
        }
    }
}]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM