Evite los bloqueadores de ventanas emergentes del navegador


Estoy desarrollando un flujo de autenticación OAuth puramente en JavaScript y quiero mostrar al usuario la ventana "conceder acceso" en una ventana emergente, pero se bloquea.

¿Cómo puedo evitar que las ventanas emergentes creadas por window.open o window.showModalDialog sean bloqueadas por los bloqueadores de ventanas emergentes de los diferentes navegadores?

Author: Mark Amery, 2010-04-06

8 answers

La regla general es que los bloqueadores de ventanas emergentes se activarán si window.open o similar es invocado desde javascript que no es invocado por acción directa del usuario. Es decir, puede llamar a window.open en respuesta a un clic de botón sin ser golpeado por el bloqueador de ventanas emergentes, pero si coloca el mismo código en un evento de temporizador, se bloqueará. La profundidad de la cadena de llamadas también es un factor: algunos navegadores más antiguos solo miran a la persona que llama inmediata, los navegadores más nuevos pueden retroceder un poco para ver si la persona que llama clic del ratón, etc. Manténgalo tan superficial como pueda para evitar los bloqueadores de ventanas emergentes.

 225
Author: dthorpe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-27 17:48:55

Basado en Jason Sebring 's muy útil consejo, y en el material cubierto aquí y allí , encontré una solución perfecta para mi caso:{[15]]}

Pseudo código con fragmentos de código Javascript:

  1. Cree inmediatamente una ventana emergente en blanco en la acción del usuario

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

    Opcional: agregue un mensaje de información "esperando". Ejemplos:

    A) Una página HTML externa: reemplace la línea anterior con

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

    B) Texto: añadir la siguiente línea debajo de la por encima de uno:

    importantStuff.document.write('Loading preview...');
    
  2. Rellénelo con contenido cuando esté listo (cuando se devuelva la llamada AJAX, por ejemplo)

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

Enriquece la llamada a window.open con las opciones adicionales que necesites.

En realidad uso esta solución para una redirección de mailto, y funciona en todos mis navegadores (Windows 7, Android). El bit _blank ayuda a que la redirección de mailto funcione en dispositivos móviles, por cierto.

¿Su experiencia? ¿Alguna forma de mejorar esto?

 128
Author: Swiss Mister,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-18 17:56:29

Además Mister post suizo, en mi caso la ventana .open se lanzó dentro de una promesa, que activó el bloqueador de ventanas emergentes, mi solución fue: en angular:

$scope.gotClick = function(){

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

    }
  );
};

Servicio de navegación:

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

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

Así es como puede abrir una nueva pestaña usando la respuesta promise y no invocando el bloqueador de ventanas emergentes.

 16
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-27 11:44:13

Como una buena práctica creo que es una buena idea probar si una ventana emergente se bloqueó y tomar medidas en caso de que. Tienes que conocer esa ventana.open tiene un valor devuelto, y ese valor puede ser null si la acción falla. Por ejemplo, en el siguiente código:

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 la ventana emergente está bloqueada, ventana.open devolverá null. Así que la función devolverá false.

Como ejemplo, imagine llamar a esta función directamente desde cualquier enlace con target="_blank": si la ventana emergente es exitosa abierto, volviendo false bloqueará la acción de enlace, de lo contrario si la ventana emergente está bloqueada, devolver true permitirá el comportamiento predeterminado (abrir nuevo _blank ventana) y seguir adelante.

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

De esta manera tendrá una ventana emergente si funciona, y una ventana _blank si ni.

Si la ventana emergente no se abre, puede:

  • abra una ventana en blanco como en el ejemplo y continúe
  • abrir una ventana emergente falsa (un iframe dentro de la página)
  • informar al usuario ("por favor permitir ventanas emergentes para este sitio")
  • abra una ventana en blanco y luego informe al usuario sucesivamente..
 14
Author: FrancescoMM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-25 11:20:26

De la API JavaScript oauth de Google:

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

Vea el área donde se lee:

Configuración de la Autenticación

La implementación del cliente de OAuth 2.0 utiliza una ventana emergente para solicitar al usuario que inicie sesión y apruebe la aplicación. La primera llamada a gapi.auth.authorize puede activar bloqueadores de ventanas emergentes, ya que abre la ventana emergente indirectamente. Para evitar que el bloqueador de ventanas emergentes al activar llamadas auth, llame a gapi.auth.init (callback) cuando se carga el cliente. La devolución de llamada suministrada se ejecutará cuando la biblioteca esté lista para realizar llamadas de autenticación.

Supongo que su relación con la respuesta real de arriba en cómo se explica si hay una respuesta inmediata, no se activará la alarma emergente. El "gapi.auth.init " está haciendo que la api suceda de inmediato.

Aplicación Práctica

Hice un microservicio de autenticación de código abierto usando node pasaporte en npm y los diversos paquetes de pasaporte para cada proveedor. Utilicé un enfoque de redirección estándar para la tercera parte dándole una URL de redirección para volver. Esto era programático para que pudiera tener diferentes lugares para redirigir de nuevo a si inicio de sesión / registro y en páginas particulares.

Github.com/sebringj/athu

Passportjs.org

 8
Author: Jason Sebring,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 04:58:11

No quería hacer la nueva página a menos que la devolución de llamada regresara con éxito, así que hice esto para simular el clic del usuario:

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
Author: user3479425,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-12 19:28:36

Probé múltiples soluciones, pero la suya es la única que realmente funcionó para mí en todos los navegadores

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

 -2
Author: pomobc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-02 22:02:55

La forma más fácil de deshacerse de esto es, que funcionó para mí muy bien -

  1. No utilice el documento.abrir().
  2. En su lugar use esto.documento.ubicación.href = location; donde location es la url a cargar

Ex:

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

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

Esto funciona muy bien. Salud

 -4
Author: Pramod Shetty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-31 00:00:20