2013-05-03 25 views
11

Podczas obsługi OAuth z serwera, takiego jak Twitter i Facebook, najprawdopodobniej przekieruje użytkownika do adresu URL z prośbą o pozwolenie aplikacji. Zwykle po kliknięciu łącza wysyłane jest żądanie do serwera za pośrednictwem AJAX, a następnie zwracany jest adres URL autoryzacji.window.open bez blokowania okienek wyskakujących za pomocą AJAX i manipulowanie window.location

Ale kiedy spróbujesz użyć window.open po odebraniu odpowiedzi, twoja przeglądarka blokuje wyskakujące okienko, co czyni go bezużytecznym. Oczywiście możesz po prostu przekierować użytkownika do nowego adresu URL, ale to psuje wrażenia użytkownika, a to jest denerwujące. Nie możesz używać IFRAMES, ale nie są one dozwolone (ponieważ nie widzisz paska lokalizacji).

Jak to zrobić?

Odpowiedz

26

Odpowiedź jest dość prosta i działa w przeglądarce bez żadnych problemów. Podczas wykonywania wywołania AJAX (będę używał jQuery w tym przykładzie), wykonaj następujące czynności. Załóżmy, że mamy formularz z dwoma przyciskami: Login with Twitter i 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> 

Następnie kod Javascript, gdzie dzieje się magia

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

Oto POC w JSFiddle http://jsfiddle.net/CNCgG/

Jest to prosty i skuteczny :)

+0

Jest to bardzo dobra praca wokół, ale jeśli używasz FB.ui() Nie sądzę, że to będzie działać. – deathemperor

+0

EDYCJA: moje złe, źle odczytałem twoje zdanie. Tak, myślę, że używanie FB.ui nie zadziała, ponieważ działa tylko wtedy, gdy możesz przekierować okno dialogowe do nowego adresu URL. Jeśli FB.ui ma odpowiednika po stronie serwera, to będzie działać. – pocesar

+1

jest to fantastycznie proste i skuteczne obejście, które zapewnia, że ​​wywoływane przez ajax pop-upy będą się koncentrować. dzięki pocesar! – neokio

8

spróbuj dodać async: false. Należy pracować

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

Dzięki temu działa również na iOS, dzięki – comeOnGetIt

+0

Dobrze wiedzieć, że działa również na iOS ... dziękuję za wskazanie tego – rajesh

+0

, ale to nie działa na chrome/(ㄒ o ㄒ)/~~ – C0de8ug