Éviter les bloqueurs de popups du navigateur

je développe un flux d'authentification neutre purement en JavaScript et je veux montrer à l'utilisateur la fenêtre" grant access " dans un popup, mais elle est bloquée.

Comment puis-je empêcher les fenêtres pop-up créées par window.open ou window.showModalDialog d'être bloquées par les bloqueurs pop-up des différents navigateurs?

120
demandé sur Mark Amery 2010-04-06 23:29:26

8 réponses

la règle générale est que les bloqueurs de popup s'engageront si window.open ou similaire est invoqué à partir de javascript qui n'est pas invoqué par l'action directe de l'utilisateur . C'est-à-dire, vous pouvez appeler window.open en réponse à un clic de bouton sans se faire frapper par le bloqueur de popup, mais si vous mettez le même code dans un événement de minuterie il sera bloqué. La profondeur de la chaîne d'appel est également un facteur - certains navigateurs plus anciens ne regardent que l'appelant immédiat, les navigateurs plus récents peuvent faire marche arrière un peu pour voir si l'appelant était un clic de souris, etc. Gardez-le aussi peu profond que vous pouvez pour éviter les bloqueurs popup.

225
répondu dthorpe 2012-08-27 17:48:55

basé sur Jason Sebring 's conseil très utile , et sur la matière couverte ici et il , j'ai trouvé une solution parfaite pour mon cas:

Pseudo code avec les snippets Javascript:

  1. créez immédiatement un popup vide sur l'action de l'utilisateur

    var importantStuff = window.open('', '_blank');
    

    optionnel: ajouter un message d'information "en attente". Exemples:

    a) une page HTML externe: remplacer la ligne ci-dessus par

    var importantStuff = window.open('http://example.com/waiting.html', '_blank');
    

    B) texte: ajouter la ligne suivante après la ligne ci-dessus:

    importantStuff.document.write('Loading preview...');
    
  2. remplissez-le de contenu lorsqu'il est prêt (lorsque L'appel AJAX est retourné, par exemple)

    importantStuff.location.href = 'http://shrib.com';
    

enrichissez l'appel à window.open avec toutes les options supplémentaires dont vous avez besoin.

j'utilise en fait cette solution pour une redirection mailto, et cela fonctionne sur tous mes navigateurs (windows 7, Android). Le bit _blank aide à la redirection du courrier pour travailler sur mobile, btw.

votre expérience? De toute façon pour améliorer cela?

128
répondu Swiss Mister 2017-12-18 17:56:29

en plus de Swiss Mister post, dans mon cas la fenêtre .ouvert a été lancé à l'intérieur d'une promesse, qui a allumé le bloqueur popup, ma solution a été: en angle:

$scope.gotClick = function(){

  var myNewTab = browserService.openNewTab();
  someService.getUrl().then(
    function(res){
        browserService.updateLocation(res.url, myNewTab);

    }
  );
};

browserService:

this.openNewTab = function(){
     var newTabWindow = $window.open();
     return newTabWindow;
}

this.updateTabLocation = function(tabLocation, tab) {
     if(!tabLocation){
       tab.close();
     }
     tab.location.href = tabLocation;
}

voici comment vous pouvez ouvrir un nouvel onglet en utilisant la réponse promise et ne pas invoquer le bloqueur de popup.

16
répondu David 2016-10-27 11:44:13

comme bonne pratique, je pense que c'est une bonne idée de tester si un popup a été bloqué et de prendre des mesures en cas. Tu dois connaître cette fenêtre.ouvrir a une valeur de retour, et cette valeur peut être nulle si l'action a échoué. Par exemple, dans le code suivant:

function pop(url,w,h) {
    n=window.open(url,'_blank','toolbar=0,location=0,directories=0,status=1,menubar=0,titlebar=0,scrollbars=1,resizable=1,width='+w+',height='+h);
    if(n==null) {
        return true;
    }
    return false;
}

si le popup est bloqué, fenêtre.ouvrir retournera null. Donc, la fonction retournera false.

comme exemple, imaginez appeler cela fonction directement à partir de n'importe quel lien avec target="_blank" : si le popup est ouvert avec succès, retour false bloque l'action du lien, sinon si le popup est bloqué, retourner true laissera le comportement par défaut (ouvrir new _blank de la fenêtre) et aller sur.

<a href="http://whatever.com" target="_blank" onclick='return pop("http://whatever.com",300,200);' >

de cette façon vous aurez un popup si cela fonctionne, et une fenêtre _blank si pas.

Si le popup ne s'ouvre pas, vous pouvez:

  • ouvrir une fenêtre vide comme dans l'exemple et continuer
  • ouvrir un faux popup (Une iframe à l'intérieur de la page)
  • informer l'utilisateur ("veuillez autoriser les popups pour ce site")
  • ouvrir une fenêtre vide et d'en informer l'utilisateur etc..
14
répondu FrancescoMM 2015-09-25 11:20:26

de L'API JavaScript de Google:

http://code.google.com/p/google-api-javascript-client/wiki/Authentication

voir la zone où il se lit:

mise en place de L'authentification

la mise en œuvre de OAuth 2.0 par le client utilise une fenêtre popup pour demander à l'utilisateur de s'inscrire et d'approuver l'application. Le premier appel à gapi.auth.autoriser peut déclencher des bloqueurs popup, car il ouvre la fenêtre popup indirectement. Pour empêcher le bloqueur de popup de se déclencher sur les appels auth, appelez gapi.auth.init(rappel) lorsque le client charge. Le callback fourni sera exécuté lorsque la bibliothèque sera prête à faire des appels auth.

je suppose que c'est lié à la réponse réelle ci-dessus dans la façon dont il explique s'il y a une réponse immédiate, il ne va pas déclencher l'alarme popup. Le " gapi.auth.init " fait en sorte que l'api se produit immédiatement.

Application Pratique

j'ai fait un microservice d'authentification open source en utilisant node passport sur npm et les différents paquets de passeports pour chaque fournisseur. J'ai utilisé une approche de redirection standard vers le Tiers lui donnant une URL de redirection pour revenir à. C'était programmatique donc je pourrais avoir différents endroits pour rediriger de nouveau à si login/inscription et sur des pages particulières.

github.com/sebringj/athu

passportjs.org

8
répondu Jason Sebring 2015-12-15 04:58:11

Je ne voulais pas faire la nouvelle page à moins que le rappel soit retourné avec succès, donc j'ai fait ceci à simuler l'utilisateur clique:

function submitAndRedirect {
  apiCall.then(({ redirect }) => {
      const a = document.createElement('a');
      a.href = redirect;
      a.target = '_blank';
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
  });
}
0
répondu user3479425 2017-09-12 19:28:36

j'ai essayé plusieurs solutions, mais la sienne est la seule qui a réellement fonctionné pour moi dans tous les navigateurs

let newTab = window.open(); newTab.location.href = url;

-2
répondu pomobc 2018-06-02 22:02:55

la façon la plus facile de se débarrasser de cela est, qui a très bien fonctionné pour moi -

  1. N'utilisez pas le document.ouvrir.)(
  2. utilisez plutôt ceci.document.emplacement.href = lieu; où est l'url à charger

Ex:

<script>
function loadUrl(location)
{
this.document.location.href = location;
}</script>

<div onclick="loadUrl('company_page.jsp')">Abc</div>

Cela fonctionne très bien. Cheers

-4
répondu Pramod Shetty 2016-01-31 00:00:20