【问题标题】:window.open without popup blocker using AJAX and manipulating the window.locationwindow.open 没有使用 AJAX 和操纵 window.location 的弹出窗口阻止程序
【发布时间】:2013-04-28 00:40:54
【问题描述】:

从服务器(例如 Twitter 和 Facebook)处理 OAuth 时,您很可能会将用户重定向到请求应用许可的 URL。通常,单击链接后,您通过 AJAX 将请求发送到服务器,然后返回授权 URL。

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

那该怎么做呢?

【问题讨论】:

    标签: ajax popup twitter-oauth facebook-oauth window.open


    【解决方案1】:

    尝试添加 async: false。它应该可以工作

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

    【讨论】:

    • 很高兴知道它也适用于 iOS...感谢您指出这一点
    【解决方案2】:

    答案很简单,可以跨浏览器运行,没有任何问题。在进行 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>
    

    然后是魔法发生的 Javascript 代码

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

    这是 JSFiddle 中的 POC http://jsfiddle.net/CNCgG/

    这简单有效:)

    【讨论】:

    • 这是一个很好的解决方法,但如果您使用的是 FB.ui(),我认为它不会起作用。
    • 编辑:我的错,我看错了你的话。是的,我认为使用 FB.ui 是行不通的,因为它只有在您可以将对话框重定向到新 URL 时才有效。如果 FB.ui 有一个服务器端对应,那么它会工作。
    • 这是一个非常简单有效的解决方法,确保 ajax 打开的弹出窗口获得焦点。谢谢pocesar!
    • 不幸的是在 iOS 上不起作用,所以不是一个很好的解决方案
    • @ThomasHeymann 感谢您指出,也许代码中的另一个步骤来检测 iOS,而不是打开窗口,直接打开 FB 地址(并​​执行 window.location.replace() 而不是 authWindow .location.replace())
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多