2013-05-03 45 views
11

当从服务器(如Twitter和Facebook)处理OAuth时,很可能会将用户重定向到请求应用程序权限的URL。通常,点击链接后,您通过AJAX将请求发送到服务器,然后返回授权URL。window.open没有弹出窗口拦截器使用AJAX和操纵window.location

但是,当您在收到答案时尝试使用window.open时,浏览器会阻止弹出窗口,使其无效。当然,你可以将用户重定向到新的URL,但这会破坏用户体验,而且很烦人。你不能使用IFRAMES,但它们是不允许的(因为你看不到地址栏)。

那么该怎么做呢?

回答

26

答案很简单,并且可以跨浏览器工作,没有任何问题。在进行AJAX调用时(我将在本例中使用jQuery),请执行以下操作。假设我们有一个带有两个按钮的窗体,Login with TwitterLogin with Facebook

<button type="submit" class="login" value="facebook" name="type">Login with Facebook</button> 
<button type="submit" class="login" value="twitter" name="type">Login with Twitter</button> 

然后在魔术发生

$(function() { 
    var 
     $login = $('.login'), 
     authWindow; 

    $login.on('click', function (e) { 
     e.preventDefault(); 
     /* We pre-open the popup in the submit, since it was generated from a "click" event, so no popup block happens */ 
     authWindow = window.open('about:blank', '', 'left=20,top=20,width=400,height=300,toolbar=0,resizable=1'); 
     /* do the AJAX call requesting for the authorize URL */ 

     $.ajax({ 
      url: '/echo/json/', 
      type: "POST", 
      data: {"json": JSON.stringify({"url": 'http://' + e.target.value + '.com'})} 
      /*Since it's a jsfiddle, the echo is only for demo purposes */ 
     }) 
     .done(function (data) { 
      /* This is where the magic happens, we simply redirec the popup to the new authorize URL that we received from the server */ 
      authWindow.location.replace(data.url); 
     }) 
     .always(function() { 
      /* You can poll if the window got closed here, and so a refresh on the main page, or another AJAX call for example */ 
     }); 
    }); 
}); 

这里的Javascript代码是的jsfiddle http://jsfiddle.net/CNCgG/

的POC这是简单而有效的:)

+0

这是一个非常好的解决方法,但如果您使用FB.ui()我不认为它会工作。 – deathemperor 2013-05-13 07:10:26

+0

编辑:我的坏,我误读你的短语。是的,我认为使用FB.ui是行不通的,因为它只有在您可以将对话框重定向到新URL时才有效。如果FB.ui有一个服务器端对应的,那么它将工作。 – pocesar 2013-05-13 14:32:18

+1

这是一个非常简单而有效的解决方法,确保ajax打开的弹出窗口获得焦点。谢谢pocesar! – neokio 2013-10-09 08:42:23

8

尝试增加异步:假的。它应该是工作

$('#myButton').click(function() { 
$.ajax({ 
    type: 'POST', 
    async: false, 
    url: '/echo/json/', 
    data: {'json': JSON.stringify({ 
     url:'http://google.com'})}, 
    success: function(data) { 
     window.open(data.url,'_blank'); 
    } 
}); 
}); 
+1

这使得它也可以在iOS上运行,谢谢 – comeOnGetIt 2015-05-18 23:16:54

+0

很高兴知道它也适用于iOS ...感谢您指出这一点 – rajesh 2016-08-22 20:12:21

+0

,但这对于chrome /(ㄒoㄒ)/ ~~不适用 – C0de8ug 2016-08-24 13:31:31

相关问题