Estoy desarrollando un flujo de autenticación OAuth puramente en JavaScript y quiero mostrarle al usuario la ventana "conceder acceso" en una ventana emergente, pero se bloquea.
¿Cómo puedo evitar que las ventanas emergentes creadas por cualquiera window.open
o que window.showModalDialog
sean bloqueadas por los bloqueadores de ventanas emergentes de los diferentes navegadores?
javascript
popup
modal-dialog
popup-blocker
Pablo Fernández
fuente
fuente
Respuestas:
La regla general es que los bloqueadores de ventanas emergentes se activarán si
window.open
se invoca o similar desde JavaScript que no es invocado por la acción directa del usuario . Es decir, puede llamarwindow.open
en respuesta a un clic en el 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 antiguos solo miran a la persona que llama inmediatamente, los navegadores más nuevos pueden retroceder un poco para ver si la persona que llamó fue un clic del mouse, etc. Manténgalo lo más superficial posible para evitar los bloqueadores de ventanas emergentes.fuente
Sobre la base de Jason Sebring 's consejo muy útil , y en las cosas cubiertos aquí y allí , he encontrado una solución perfecta para mi caso:
Pseudocódigo con fragmentos de Javascript:
crear inmediatamente una ventana emergente en blanco en la acción del usuario
Opcional: agregue algún mensaje de información "en espera". Ejemplos:
a) Una página HTML externa: reemplace la línea anterior con
b) Texto: agregue la siguiente línea debajo de la anterior:
llénelo con contenido cuando esté listo (cuando se devuelve la llamada AJAX, por ejemplo)
Enriquezca la llamada
window.open
con cualquier opción adicional que necesite.De hecho, uso esta solución para una redirección de mailto, y funciona en todos mis navegadores (Windows 7, Android). El
_blank
bit ayuda a que la redirección de mailto funcione en dispositivos móviles, por cierto.¿Tu experiencia? ¿Alguna forma de mejorar esto?
fuente
Whatever it is you intend to do, there is a better way than a popup window
jajaja Extraña generalización. Al cliente le gustaría que la página en la que se autenticaron permanezca abierta, y que el nuevo sitio / página de destino después de la autenticación se abra en una nueva pestaña. Sí, no es mi idea de una excelente experiencia de usuario ... pero parece razonableimportantStuff.close
para cerrar la nueva pestaña y proporcionar y alertar en la página original.Además, la publicación Swiss Mister, en mi caso, el window.open se lanzó dentro de una promesa, que activó el bloqueador de ventanas emergentes, mi solución fue: en angular:
browserService:
así es como puede abrir una nueva pestaña utilizando la respuesta de promesa y no invocando el bloqueador de ventanas emergentes.
fuente
const tab = window.open(); observable.subscribe(dataUrl => tab.location.href = dataUrl);
.then
respuesta y por eso me confundí tanto: / SRY ...Como buena práctica, creo que es una buena idea probar si una ventana emergente fue bloqueada y tomar medidas por si acaso. Debe saber que window.open tiene un valor de retorno, y ese valor puede ser nulo si la acción falla. Por ejemplo, en el siguiente código:
si la ventana emergente está bloqueada, window.open devolverá nulo. Entonces la función devolverá falso.
Si la ventana emergente no se abre, puede:
fuente
de la API de JavaScript oauth de Google:
http://code.google.com/p/google-api-javascript-client/wiki/Authentication
Vea el área donde se lee:
Configuración de 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 se active en llamadas de autenticación, llame a gapi.auth.init (devolución de llamada) 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 está relacionado con la respuesta real anterior en cómo explica que si hay una respuesta inmediata, no activará la alarma emergente. El "gapi.auth.init" está haciendo que la API ocurra de inmediato.
Aplicación práctica
Hice un microservicio de autenticación de código abierto usando el pasaporte de nodo en npm y los diversos paquetes de pasaportes para cada proveedor. Utilicé un enfoque de redireccionamiento estándar para la tercera parte, dándole una URL de redireccionamiento para volver. Esto fue programático, por lo que podría tener diferentes lugares para redirigir de nuevo si inicio de sesión / registro y en páginas particulares.
github.com/sebringj/athu
passportjs.org
fuente
Probé varias soluciones, pero esta es la única que realmente funcionó para mí en todos los navegadores.
let newTab = window.open(); newTab.location.href = url;
fuente
url
? No está asignado.http://example.com
window.open()
no se puede abrir una nueva ventana mediante programación y, si es necesario, esa respuesta es una de las opciones. Con lanewTab
variable a la que hacemos referenciawindow.open()
y luego podemos llamarla, insertar laurl
que necesitamos, en mi caso url de algún blob, y la nueva pestaña se abrirá con la url ingresada.No quería hacer la nueva página a menos que la devolución de llamada devuelve correctamente, así que hice esto para simular el clic del usuario:
fuente
La forma más fácil de deshacerse de esto es:
Ej:
Esto funcionó muy bien para mí. Salud
fuente