window.close y self.close no cierran la ventana en Chrome

174

El problema es que cuando invoco window.close()o self.close()no cierra la ventana. Ahora parece existir la creencia de que en Chrome no se puede cerrar mediante script ninguna ventana que no se haya creado. Eso es evidentemente falso, pero independientemente de lo que se supone que debe seguir haciendo, incluso si se requiere que aparezca una alerta para confirmar. Estos no están sucediendo.

Entonces, ¿alguien tiene un método real, funcional y comprobado para cerrar una ventana usando algo como javascript:window.close()o javascript:self.close()que realmente hace lo que se espera y algo que sucede bien en todos los navegadores que NO están basados ​​en Chrome? Cualquier sugerencia sería muy apreciada y estoy buscando una solución específica de Javascript, nada de JQuery o implementación de terceros.

Actualización: Si bien gran parte de lo que se ha sugerido tiene serias limitaciones y problemas de usabilidad, la última sugerencia (específica de TamperMonkey) que se usa // @grant window.closeen el encabezado del script a menudo hará el truco incluso en aquellas pestañas que normalmente no pueden manejar el método de cierre. Si bien no es del todo ideal y no se generaliza en todos los casos, es una buena solución en mi caso.

GµårÐïåñ
fuente
window.close()me funciona en cromo.
puré
3
@ GµårÐïåñ: Umm, no, no lo es. No tiene nada que ver con el idioma. Es una función implementada por los navegadores. Si puede escribir un ejemplo mínimo que muestre cómo window.closeno funciona como debería, creo que puede ser más útil que decir "no funciona".
Blender
3
Te di DOS ejemplos. <a href="javascript:window.close">CLOSE</a>
Explicándolo
3
guardián que es JavaScript incorrecto. Prueba window.close () y funciona. window.close es solo un nombre de variable y no llamará a la función (al menos no lo hace cuando lo pruebo en Chrome 37). Cuando cambio su ejemplo a window.close () funciona en Chrome 37.
George
3
GµårÐïåñ Lo que dijo @George NO es discutible (a menos que haya entendido mal el significado de la palabra). Tiene razón al afirmar que tiene un error sintáctico en el javascript en sus ejemplos, y si tiene el mismo error en el código de su aplicación, entonces esta es probablemente la causa de su problema. Sin embargo, si estos son solo errores tipográficos en sus ejemplos, entonces debe corregirlos para obtener mejores respuestas.
Superole

Respuestas:

187

JavaScript ordinario no puede cerrar ventanas willy-nilly. Esta es una característica de seguridad, introducida hace un tiempo, para detener varias hazañas y molestias maliciosas.

De la última especificación de trabajo parawindow.close() :

El close()método en los objetos de Windows debería, si se cumplen todas las condiciones siguientes, cerrar el contexto de exploración A :

  • El contexto de exploración A correspondiente se puede cerrar mediante script .
  • El contexto de navegación del guión titular es familiarizarse con el contexto de navegación A .
  • Se deja que el contexto de navegación del guión corresponde a navegar en el contexto de navegación A .

Un contexto de exploración se puede cerrar mediante secuencia de comandos si es un contexto de exploración auxiliar creado por una secuencia de comandos (a diferencia de una acción del usuario), o si se trata de un contexto de exploración cuyo historial de sesión contiene solo un documento.

Esto significa que, con una pequeña excepción, no se debe permitir que javascript cierre una ventana que no fue abierta por ese mismo javascript.

Chrome permite esa excepción, que no se aplica a los scripts de usuario, sin embargo, Firefox no. La implementación de Firefox dice :

Este método solo se puede llamar para ventanas que fueron abiertas por un script usando el window.openmétodo.


Si intenta utilizar window.closeun Greasemonkey / Tampermonkey / userscript obtendrá:
Firefox: el mensaje de error, " Scripts may not close windows that were not opened by script."
Chrome: simplemente falla en silencio.



La solución a largo plazo:

La mejor manera de lidiar con esto es hacer una extensión de Chrome y / o un complemento de Firefox en su lugar. Estos pueden cerrar de manera confiable la ventana actual.

Sin embargo, dado que los riesgos de seguridad, planteados por window.close, son mucho menores para un script Greasemonkey / Tampermonkey; Greasemonkey y Tampermonkey podrían proporcionar razonablemente esta funcionalidad en su API (esencialmente empaquetando el trabajo de extensión para usted).
Considere hacer una solicitud de función.



Las soluciones hacky:

Chrome es actualmente vulnerable al exploit de "auto redirección". Entonces, un código como este solía funcionar en general:

open(location, '_self').close();

Este es un comportamiento defectuoso, IMO, y ahora (a partir de abril de 2015) está bloqueado en su mayoría. Seguirá funcionando desde el código inyectado solo si la pestaña está recién abierta y no tiene páginas en el historial de navegación. Por lo tanto, solo es útil en un conjunto muy pequeño de circunstancias.

Sin embargo, una variación aún funciona en Chrome (v43 y v44) más Tampermonkey (v3.11 o posterior) . Utilice una explícita @granty simple window.close(). P.EJ:

// ==UserScript==
// @name        window.close demo
// @include     http://YOUR_SERVER.COM/YOUR_PATH/*
// @grant       GM_addStyle
// ==/UserScript==

setTimeout (window.close, 5000);

Gracias a zanetu por la actualización. Tenga en cuenta que esto no funcionará si solo hay una pestaña abierta. Solo cierra pestañas adicionales.


Firefox es seguro contra ese exploit. Entonces, la única forma de JavaScript es paralizar la configuración de seguridad, un navegador a la vez.

Puede abrir about:configy establecer
allow_scripts_to_close_windowsa true.

Si su guión es para uso personal, continúe y hágalo. Si le pide a alguien más que active esa configuración, sería inteligente y justificado rechazarlo con prejuicios.

Actualmente no hay una configuración equivalente para Chrome.

Brock Adams
fuente
3
Hola mi amigo, me alegro finalmente de tener noticias tuyas. Solo una nota, en Fx puedes saltear esa limitación cambiando el valor dom.allow_scripts_to_close_windows;falsea, truepero supongo que no hay nada en Chrome sin piratear la fuente / reconstrucción, que es como lo solucioné por ahora. Sé y he hablado con el desarrollador de TM y en el reciente alfa / beta lo hemos puesto como una opción de compatibilidad (configuración del script) para que se ejecute en el estilo de hombre en el medio, funciona. Supongo que, salvo los hacks, no tenemos una solución limpia, lástima.
GµårÐïåñ
3
Si alguien tiene problemas con window.close o la diferencia de comportamiento particular entre los navegadores, lea esta respuesta con mucho cuidado; realmente tiene toda la información correcta.
Bron Davies
¿Hay alguna manera de verificar si la ventana se abrió por script o no? (Necesito mostrar / ocultar un botón de retroceso, no quiero usar el hack) Gracias EDITAR: window.opener === null
Cétia
Desde Chrome 36.0.1985.125 MIÉRCOLES, 16 DE JULIO DE 2014, es posible que las soluciones alternativas no funcionen, detalle en mi respuesta.
swcool
2
window.close()funcionará en Tampermonkey si establece @grantun valor distinto de none. Ver este hilo .
zanetu
32

Chrome solucionó los problemas de seguridad en la versión 36.0.1985.125

Chrome 36.0.1985.125 MIÉRCOLES, 16 DE JULIO DE 2014 Nota de la versión

Desde mi observación, esta actualización solucionó el problema al usar window.close()para cerrar la ventana emergente. Verá esto en la consola cuando falla, "Los scripts pueden cerrar solo las ventanas que abrió". Eso significa que las soluciones alternativas (respuesta de Brock Adams) pueden no funcionar en la última versión.

Entonces, en las versiones anteriores de Chrome, el bloque de código a continuación puede funcionar, pero no con esta actualización.

window.open('', '_self', '');
window.close();

Para esta actualización, debe actualizar su código en consecuencia para cerrar la ventana emergente. Una de las soluciones es tomar la identificación de la ventana emergente y usar

chrome.windows.remove(integer windowId, function callback)

Método para eliminarlo. La extensión de Chrome API de Windows se puede encontrar en chrome.windows .

En realidad, mi extensión de Chrome MarkView estaba enfrentando este problema y tuve que actualizar mi código para que funcione para esta actualización de Chrome. Por cierto, MarkView es una herramienta para leer y escribir Awesome Markdown Files, proporciona características que incluyen el esquema de contenido, tablas clasificables y resaltado de sintaxis de bloque de código con número de línea.

También creé esta publicación , cualquier comentario es bienvenido.

swcool
fuente
2
El hack correcto es open(location, '_self').close();: tenga en cuenta el uso del valor de retorno de open(). Esto todavía funciona en Chrome36.0.1985.125 m
Brock Adams
En mi caso, acabo de probar nuevamente con open(location, '_self').close();, recibí un error "No autorizado" en esto. Este error es diferente con 'window.close () (warning on this"Scripts may close only the windows that were opened by it."). It looked like open (location,' _self '). Close () ; `avanzó un poco, pero en mi caso no puede completarse. Gracias @ brock-adams por el comentario.
swcool
Tengo mecanografiado y cuando lo pongo chrome.windows.removedice que no pude encontrar el símbolo de cromo. ¿Cómo puedo resolver esto? ¿Necesito agregar algún tipo de referencia?
DevT
@devt chrome.windows.remove es la API de extensión de Chrome, su programa de extensión de Chrome debería reconocer su javascript. Puede probarlo dentro de background.js, en su extensión de Chrome manifest.json necesita tener: "background": {"scripts": ["background.js"], ...},
swcool
Había eliminado la función de inicio de sesión MarkView para que los usuarios puedan acceder libremente. Entonces, el ejemplo que mencioné anteriormente no está disponible ahora.
swcool
21

En tampermonkey ahora puedes usar

// @grant        window.close

Y luego simplemente llame

window.close();
balping
fuente
He confirmado que esto funciona en muchos casos, pero de vez en cuando es obstinado pero mejor que nada, gracias. Lo agregaré a la publicación.
GµårÐïåñ
2
Solo como una nota: No funciona para mí en Greasemonkey 3.10
mt025
17

Estoy usando el método publicado por Brock Adams e incluso funciona en Firefox, si es iniciado por el usuario.

open(location, '_self').close();

Lo llamo presionando un botón para que sea iniciado por el usuario , y todavía funciona bien con Chrome 35-40, Internet Explorer 11, Safari 7-8 y TAMBIÉN Firefox 29-35. Probé usando la versión 8.1 de Windows y Mac OS X 10.6, 10.9 y 10.10 si eso es diferente.


Código de ventana de cierre automático (en la página que se cierra)

El código completo que se utilizará en la ventana abierta por el usuario que puede cerrarse a sí mismo:

window_to_close.htm

JavaScript:

function quitBox(cmd)
{   
    if (cmd=='quit')
    {
        open(location, '_self').close();
    }   
    return false;   
}

HTML:

<input type="button" name="Quit" id="Quit" value="Quit" onclick="return quitBox('quit');" />

Pruebe esta página de prueba: (ahora probado en Chrome 40 y Firefox 35)

http://browserstrangeness.bitbucket.io/window_close_tester.htm


Código de apertura de ventana (en una página que abre la página anterior)

Para que esto funcione, la compatibilidad entre navegadores impuesta por la seguridad requiere que la ventana que se va a cerrar ya debe haber sido abierta por el usuario haciendo clic en un botón dentro del mismo dominio del sitio.

Por ejemplo, la ventana que usa el método anterior para cerrarse, se puede abrir desde una página usando este código (código proporcionado desde mi página de ejemplo vinculada anteriormente):

window_close_tester.htm

JavaScript:

function open_a_window() 
{
    window.open("window_to_close.htm"); 

    return false;
}

HTML:

<input type="button" onclick="return open_a_window();" value="Open New Window/Tab" />
Jeff Clayton
fuente
Olvidé las excepciones iniciadas por el usuario; buena atrapada. Sin embargo, creo que la mayoría de los usuarios de script quieren una operación completamente automática. Ya tienen un práctico mecanismo de cierre iniciado por el usuario: esa pequeña X en la esquina superior derecha. (^_^)
Brock Adams
1
De alguna manera, esto no funciona para mí. Ni en Firefox 30 ni en Chrome 37. Todo lo que hace es hacer que la página quede en blanco (comportamiento realmente extraño). Mi código es <button onclick="open(location,'_self').close()" >Close Window</button>. ¿Estoy haciendo algo obviamente mal? Me parece que esto también es iniciado por el usuario. Tenga en cuenta que obtengo el mismo resultado si uso a <button>o an <input type="button">.
LordOfThePigs
Se agregó una página de prueba arriba en la respuesta para usted.
Jeff Clayton
@YumYumYum gracias por la publicación, bitbucket.org cambió el enlace a bitbucket.io recientemente - solucionado en la respuesta ahora
Jeff Clayton
A mí me funciona (tener un botón en la página para cerrar la ventana). Lo que no funcionó fue: window.open('', '_self', ''); window.close(); pero funcionaba con open(location, '_self').close();
krystonen
10

Muchas personas todavía están tratando de encontrar una manera de cerrar el navegador Chrome con JavaScript. El siguiente método solo funciona cuando usas Chrome como lanzador de aplicaciones: ¡kiosco, por ejemplo!

He probado lo siguiente:

Estoy usando la siguiente extensión: Cerrar Kiosk

Estoy siguiendo las instrucciones de uso y parece funcionar bien (asegúrese de borrar el caché mientras realiza las pruebas). El javascript que uso es (adjunto al evento click):

window.location.href = '/closekiosk';

Espero que eso ayude a alguien, ya que es la única solución de trabajo que he encontrado.

Nota: Parece que la extensión se ejecuta en segundo plano y agrega un icono de bandeja de Chrome. Tiene la siguiente opción marcada: "Dejar que Chrome se ejecute en segundo plano" (o texto similar). Es posible que tengas que jugar con él, hasta que funcione para ti. Lo desmarqué y ahora funciona bien.

Ministro
fuente
9

A pesar de pensar que es "evidentemente falso", lo que usted dice "parece ser una creencia" es realmente correcto. La documentación de Mozilla para window.close dice

Este método solo se puede llamar para ventanas que fueron abiertas por un script usando el método window.open. Si la ventana no fue abierta por una secuencia de comandos, aparece el siguiente error en la consola de JavaScript: las secuencias de comandos no pueden cerrar ventanas que no fueron abiertas por la secuencia de comandos

Dices que se supone que "todavía debe hacerlo", pero no creo que encuentres ninguna referencia que respalde eso, ¿tal vez has recordado algo mal?

Gareth
fuente
9

Encontré una nueva forma que me funciona perfectamente

var win = window.open("about:blank", "_self");
win.close();
Gerardo Abdo
fuente
1
Esto es 2017 y sigo teniendo el error de "Es posible que los scripts no cierren ventanas que no fueron abiertas por el script".
Rotimi
Buen truco para el botón de confirmación de IE 11.
Gopal00005
Funciona en Chrome y Firefox
Vineeth Pradhan
1
Este agujero parece haber sido llenado. No sé cuándo, pero estoy usando la última versión de desarrollo 84.x. La página en blanco se carga pero el cierre no se dispara.
Scott Christensen
4

El siguiente código funcionó para mí:

window.open('location', '_self', '');
window.close();

Probado en Chrome 43.0.2357.81

DfrDkn
fuente
¿Puedes agregar tu versión de Chrome por favor?
Stephan
Mi versión de Chrome es 43.0.2357.81.
DfrDkn
77
Para mí, eso solo reemplaza la ventana actual, con una ventana en / location.
alianos-
@ alianos- para mí también.
RicardoGonzales
1
No funciona en el último Chrome: versión 61.0.3163.100 (versión oficial) (64 bits)
Subhajit
1

Esto puede ser viejo, pero respondamos.

Yo uso top.close () para cerrar una pestaña. window.close () u otro abierto ... cerrar no funcionó para mí.

Soley
fuente
11
Esto también sufre el "Scripts may not close windows that were not opened by script."problema mencionado en otras respuestas.
kad81
1
Por favor, dé una solución a su respuesta. por favor no discuta el problema solo en su respuesta.
Bimal Das
0

En mi caso, la página necesitaba cerrarse, pero puede haber sido abierta por un enlace y, por window.closelo tanto, podría fallar.

La solución que elegí es emitir el window.close, seguido de un window.setTimeoutque redirige a una página diferente.

De esa manera, si window.closetiene éxito, la ejecución en esa página se detiene, pero si falla, en un segundo, redirigirá a una página diferente.

window.close();
window.setTimeout(function(){location.href = '/some-page.php';},1000);
usuario2182349
fuente
0

Esta respuesta de Brock me funcionó. No se debe permitir que javascript cierre una ventana que no fue abierta por ese mismo javascript.

Solo puedo cerrar la ventana secundaria si lo voy a cerrar desde el javascript primario. entonces en mi padre puedo hacer algo como esto.

var myChildWindow;

function openWindow(){
myChildWindow = window.open("","myChildWindow","width=400,height=400");
}

function closeWindow() {
myChildWindow.close();
}
Crismograma
fuente
-1

También puede intentar usar mi código a continuación. Esto también lo ayudará a redirigir su ventana principal:

Padre:

<script language="javascript">

function open_a_window() 
{
    var w = 200;
        var h = 200;
        var left = Number((screen.width/2)-(w/2));
        var tops = Number((screen.height/2)-(h/2));

        window.open("window_to_close.html", '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+tops+', left='+left);

   return false;
}

// opener:
window.onmessage = function (e) {
  if (e.data === 'location') {
    window.location.replace('https://www.google.com');
  }
};

</script>

<input type="button" onclick="return open_a_window();" value="Open New Window/Tab" />

Surgir:

<!DOCTYPE html>
<html>
<body onload="quitBox('quit');">

<h1>The window closer:</h1>

<input type="button" onclick="return quitBox('quit');" value="Close This Window/Tab" /> 


<script language="javascript">

function quitBox(cmd) 
{      
    if (cmd=='quit')    
    {   
       window.opener.postMessage('location', '*');
       window.open(location, '_self').close();    
    }     
    return false;   
}

</script>

</body>
</html>
Harshal Lonare
fuente
-2

Solo si abre una nueva ventana usando window.open (), la nueva ventana podrá cerrarse usando el código como he mencionado anteriormente. Esto funciona perfectamente para mí :) Nota: nunca use href para abrir la página en una pestaña nueva. Window.close () no funciona con "href". Use window.open () en su lugar.

DfrDkn
fuente
1
Solo está reemplazando la ventana actual. No más.
RicardoGonzales
-3

Quería compartir mi "solución" con este problema. Parece que la mayoría de nosotros estamos tratando de cerrar una ventana del navegador en una sesión estándar del navegador, donde un usuario visita un sitio web u otro, después de haber visitado otros sitios web, y antes de visitar más.

Sin embargo, mi situación es que estoy creando una aplicación web para un dispositivo que esencialmente será lo único que hará el dispositivo. Lo inicias, inicia Chrome y navega a nuestra aplicación. Ni siquiera está conectado a Internet, los servidores con los que habla están en nuestros contenedores Docker locales. El usuario necesita una forma de cerrar la aplicación (también conocida como Chrome) para poder acceder al terminal para realizar actualizaciones del sistema.

Entonces se inicia, inicia Chrome en modo quiosco, en la dirección correcta ya. Esto sucede para satisfacer fácilmente la segunda opción en la especificación:

Un contexto de exploración se puede cerrar mediante secuencia de comandos si es un contexto de exploración auxiliar creado por una secuencia de comandos (a diferencia de una acción del usuario), o si se trata de un contexto de exploración de nivel superior cuyo historial de sesión contiene solo un documento.

¡Simplemente llamar window.close()desde mi aplicación de kiosco simplemente funciona !

Jonathan Tuzman
fuente
-5

Pruebe algo como esto onclick = "return self.close ()"

Ragven
fuente