2013-05-03 23 views
11

Quando si ha a che fare con OAuth dal server, come Twitter e Facebook, molto probabilmente si reindirizza l'utente a un URL che richiede l'autorizzazione dell'app. Di solito, dopo aver fatto clic su un collegamento, si invia la richiesta al server, tramite AJAX, e quindi si restituisce l'URL di autorizzazione.window.open senza blocco popup utilizzando AJAX e manipolando il window.location

Ma quando si tenta di utilizzare window.open quando viene ricevuta la risposta, il browser blocca il popup, rendendolo inutile. Certo, puoi semplicemente reindirizzare l'utente al nuovo URL, ma questo corrompe l'esperienza dell'utente, in più è fastidioso. Non è possibile utilizzare IFRAMES, ma non sono consentiti (perché non è possibile visualizzare la barra degli indirizzi).

Quindi come si fa?

risposta

26

La risposta è abbastanza semplice e funziona su browser senza problemi. Durante la chiamata AJAX (userò jQuery in questo esempio), procedi come segue. Supponiamo di avere un modulo con due pulsanti, Login with Twitter e 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> 

Poi il codice Javascript in cui avviene la 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 */ 
     }); 
    }); 
}); 

Ecco il POC in JSFiddle http://jsfiddle.net/CNCgG/

Questo è semplice ed efficace :)

+0

Questo è un ottimo lavoro ma se si utilizza FB.ui() non penso che funzionerà. – deathemperor

+0

EDIT: mio male, ho interpretato male la tua frase. Sì, penso che l'uso di FB.ui non funzioni, perché funziona solo se puoi reindirizzare la finestra di dialogo a un nuovo URL. Se FB.ui ha una controparte lato server, funzionerà. – pocesar

+1

questa soluzione è una soluzione estremamente semplice ed efficace che consente di attivare i popup aperti da ajax. grazie pocesar! – neokio

8

Prova ad aggiungere async: false. Dovrebbe funzionare

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

Questo funziona anche su iOS, grazie – comeOnGetIt

+0

Buono a sapersi che funziona anche per iOS ... grazie per aver segnalato questo – rajesh

+0

ma questo non funziona su chrome/(ㄒ o ㄒ)/~~ – C0de8ug