window.open without popup blocker using AJAX and manipulating the window.location
Asked Answered
C

2

11

When dealing with OAuth from the server, such as Twitter and Facebook, you most likely will redirect the user to an URL asking for app permission. Usually, after clicking a link, you send the request to the server, via AJAX, and then return the authorization URL.

But when you try to use window.open when the answer is received, your browser blocks the popup, making it useless. Of course, you can just redirect the user to the new URL, but that corrupts the user experience, plus it's annoying. You can't use IFRAMES, but they are not allowed (because you can't see the location bar).

So how to do it?

Cereus answered 3/5, 2013 at 14:52 Comment(0)
C
28

The answer is quite simple, and works cross browser without any issues. When doing the AJAX call (I'll be using jQuery in this example), just do the following. Suppose we have a form with two buttons, Login with Twitter and Login 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>

Then the Javascript code where the magic happens

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

Here is the POC in JSFiddle http://jsfiddle.net/CNCgG/

This is simple and effective :)

Cereus answered 3/5, 2013 at 14:52 Comment(6)
This is a very good work around but if you are using FB.ui() I don't think it will work.Heffner
EDIT: my bad, I misread your phrase. Yes, I think using FB.ui it won't work, because it only works if you can redirect the dialog to a new URL. If the FB.ui have a server-side counterpart, then it will work.Cereus
this is a fantastically simple and effective workaround making sure ajax-opened popups get focus. thanks pocesar!Kwasi
unfortunately doesn't work on iOS so not really a good solutionLustick
@ThomasHeymann thanks for pointing out, maybe another step in the code to detect iOS and instead of opening a window, open the FB address directly (and do a window.location.replace() instead of authWindow.location.replace())Cereus
Nice work, this helped get rid of the popup, assigning the popup to a window and then replacing its location, it also allows me to still access the parent variables. thanks!Intermediacy
I
8

Try adding async: false. It should be working

$('#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');
    }
});
});
Incur answered 15/5, 2014 at 22:21 Comment(1)
Good to know that it works for iOS as well...thank you for pointing this outIncur

© 2022 - 2024 — McMap. All rights reserved.