window.close e self.close não fecham a janela no Chrome

174

O problema é que quando eu invoco window.close()ou self.close()ele não fecha a janela. Agora, parece haver uma crença de que no Chrome você não pode fechar por script qualquer janela que não seja criada. Isso é evidentemente falso, mas independentemente disso ainda deve ser feito, mesmo que seja necessário exibir um alerta para confirmar. Isso não está acontecendo.

Então, alguém tem um método real, funcional e comprovado de fechar uma janela usando algo como javascript:window.close()ou javascript:self.close()que realmente faz o que é esperado e algo que acontece muito bem em todos os navegadores que NÃO são baseados no Chrome? Qualquer sugestão seria muito apreciada e estou procurando uma solução específica para Javascript, nada de JQuery ou implementação de terceiros.

Atualização: Embora muito do que foi sugerido tenha sérias limitações e problemas de usabilidade, a sugestão mais recente (específica para o TamperMonkey) usada // @grant window.closeno cabeçalho do script geralmente faz o truque mesmo nas guias que normalmente não conseguem lidar com o método close. Embora não seja inteiramente ideal e não generalize para todos os casos, é uma boa solução no meu caso.

GµårÐïåñ
fonte
window.close()funciona para mim no chrome.
puré de
3
@ GµårÐïåñ: Umm, não, não é. Não tem nada a ver com o idioma. É uma função implementada pelos navegadores. Se você pode escrever um exemplo mínimo mostrando como window.closenão está funcionando da maneira que deveria, acho que pode ser mais útil do que dizer "não funciona".
Blender
3
Eu te dei dois exemplos. Soletrando-o para você, #<a href="javascript:window.close">CLOSE</a>
04713
3
guardião que é javascript impróprio. Experimente window.close () e funciona. window.close é apenas um nome de variável e não chama a função (pelo menos quando o testo no chrome 37). Quando eu mudar o seu exemplo para window.close () funciona no Chrome 37.
George
3
GµårÐïåñ O que @George disse NÃO é discutível (a menos que eu não tenha entendido totalmente o significado da palavra). Ele está certo ao afirmar que você tem um erro sintático no javascript nos seus exemplos e se você tiver o mesmo erro no código do aplicativo, é mais do que provável a causa do seu problema. Se, no entanto, esses são apenas erros de digitação em seus exemplos, você deve corrigi-los para obter melhores respostas.
Superole 06/02

Respostas:

187

O javascript comum não pode fechar as janelas à vontade. Esse é um recurso de segurança, introduzido há um tempo atrás, para impedir várias explorações e aborrecimentos maliciosos.

Das especificações de trabalho mais recentes parawindow.close() :

O close()método nos objetos Window deve, se todas as seguintes condições forem atendidas, fechar o contexto de navegação A :

  • O contexto de navegação correspondente A pode ser fechado por script .
  • O contexto de navegação do script titular é familiarizado com o contexto de navegação A .
  • O contexto navegar do script titular está autorizado a navegar no contexto de navegação A .

Um contexto de navegação pode ser fechado por script se for um contexto de navegação auxiliar criado por um script (em oposição a uma ação do usuário) ou se for um contexto de navegação cujo histórico da sessão contenha apenas um documento.

Isso significa que, com uma pequena exceção, o javascript não deve fechar uma janela que não foi aberta pelo mesmo javascript.

O Chrome permite essa exceção - que não se aplica aos scripts dos usuários - no entanto, o Firefox não. A implementação do Firefox afirma claramente :

Este método só pode ser chamado para janelas que foram abertas por um script usando o window.openmétodo


Se você tentar usar window.closeum Greasemonkey / Tampermonkey / userscript, receberá:
Firefox: A mensagem de erro, " Scripts may not close windows that were not opened by script."
Chrome: falha silenciosamente.



A solução a longo prazo:

A melhor maneira de lidar com isso é criar uma extensão do Chrome e / ou complemento do Firefox. Eles podem fechar com segurança a janela atual.

No entanto, como os riscos à segurança, representados por window.close, são muito menores para um script Greasemonkey / Tampermonkey; Greasemonkey e Tampermonkey poderiam fornecer razoavelmente essa funcionalidade em sua API (essencialmente empacotando o trabalho de extensão para você).
Considere fazer uma solicitação de recurso.



As soluções alternativas hacky:

Atualmente, o Chrome estava vulnerável à exploração de "redirecionamento automático". Portanto, códigos como este costumavam funcionar em geral:

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

Esse é um comportamento de buggy, IMO, e está agora (em abril de 2015) bloqueado. Ele ainda funcionará a partir do código injetado apenas se a guia for aberta recentemente e não tiver páginas no histórico de navegação. Portanto, é útil apenas em um conjunto muito pequeno de circunstâncias.

No entanto, uma variação ainda funciona no Chrome (v43 e v44) e no Tampermonkey (v3.11 ou posterior) . Use um explícito @grante simples window.close(). POR EXEMPLO:

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

setTimeout (window.close, 5000);

Obrigado a zanetu pela atualização. Observe que isso não funcionará se houver apenas uma guia aberta. Ele fecha apenas guias adicionais.


O Firefox é seguro contra essa exploração. Portanto, a única maneira de javascript é prejudicar as configurações de segurança, um navegador de cada vez.

Você pode abrir about:confige configurar
allow_scripts_to_close_windowscomo true.

Se seu script é para uso pessoal, vá em frente e faça isso. Se você pedir a alguém para ativar essa configuração, eles seriam inteligentes e justificados, recusando-se com preconceito.

No momento, não há configurações equivalentes para o Chrome.

Brock Adams
fonte
3
Ei, meu amigo, feliz em finalmente ouvir de você. Apenas uma nota, em Fx você pode ignorar essa limitação por lançando o dom.allow_scripts_to_close_windows;falseque true, mas acho que nada no Chrome sem cortar a fonte / reconstrução que é como eu comecei em torno dele por agora. Eu sei e conversei com o desenvolvedor da TM e, no recente alpha / beta, colocamos como uma opção de compatibilidade (configuração do script) para executar no estilo man-in-the-middle, funciona. Acho que, além dos hacks, não temos solução limpa, pena.
GμårÐïåñ
3
Se alguém tiver problemas com o window.close ou a diferença de comportamento específica entre os navegadores, leia esta resposta com muito cuidado - ele realmente possui todas as informações corretas.
Bron Davies
Existe uma maneira de verificar se a janela foi aberta por script ou não? (Eu preciso mostrar / ocultar um botão Voltar, não quero usar o hack) Obrigado EDIT: window.opener === null
CETIA
Desde o Chrome 36.0.1985.125 QUARTA-FEIRA, 16 DE JULHO DE 2014, as soluções alternativas hacky podem não funcionar, detalhem minha resposta.
swcool
2
window.close()funcionará em Tampermonkey se você definir @grantum valor diferente de none. Veja este tópico .
Zanetu 27/08/2015
32

Chrome Corrigido os problemas de segurança na versão 36.0.1985.125

Chrome 36.0.1985.125 QUARTA-FEIRA, 16 DE JULHO DE 2014 Nota da versão

Pela minha observação, esta atualização corrigiu o problema de usar window.close()para fechar a janela pop-up. Você verá isso no console quando falhar: "Os scripts podem fechar apenas as janelas que foram abertas por ele". Isso significa que as soluções alternativas hacky (resposta de Brock Adams) podem não funcionar na versão mais recente.

Portanto, nas versões lançadas anteriormente do Chrome, o bloco de códigos abaixo pode funcionar, mas não com esta atualização.

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

Para esta atualização, você deve atualizar seu código de acordo para fechar a janela pop-up. Uma das soluções é pegar o ID da janela pop-up e usar

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

método para removê-lo. A API do Windows para extensão do Chrome pode ser encontrada em chrome.windows .

Na verdade, minha extensão do Chrome MarkView estava enfrentando esse problema e tive que atualizar meu código para fazê-lo funcionar nesta atualização do Chrome. A propósito, o MarkView é uma ferramenta para ler e gravar arquivos impressionantes do Markdown, fornece recursos que incluem estrutura de tópicos de conteúdo, tabelas classificáveis ​​e destaque da sintaxe do bloco de código com o número da linha.

Eu também criei este post , todos os comentários são bem-vindos.

swcool
fonte
2
O hack correto é open(location, '_self').close();- observe o uso do valor de retorno de open(). Isso ainda funciona no Chrome36.0.1985.125 m
Brock Adams
No meu caso, eu apenas testei novamente com o open(location, '_self').close();erro "Não autorizado". Este erro é diferente com 'window.close () (warning on this"Scripts may close only the windows that were opened by it."). It looked like open (location,' _self '). Close (); `avançou um pouco, mas não pode ser concluído no meu caso. Obrigado @ brock-adams pelo comentário.
swcool
Eu tenho datilografado e quando coloco chrome.windows.removediz que não foi possível encontrar o símbolo chrome. Como posso resolver isto? preciso adicionar algum tipo de referência?
DevT
@devt chrome.windows.remove é a API de extensão do Chrome, seu javascript deve ser reconhecido pelo seu programa de extensão do chrome. Você pode experimentá-lo dentro background.js, em sua chrome extensão manifest.json você precisa ter: "background": { "scripts": [ "background.js"], ...},
swcool
Eu havia removido a função de login do MarkView para os usuários acessarem livremente. Portanto, o exemplo mencionado acima não está disponível agora.
swcool
21

No tampermonkey agora você pode usar

// @grant        window.close

E então simplesmente chame

window.close();
balping
fonte
Confirmei que isso funciona em muitos casos, mas ainda teimosos ocasionais, mas melhor que nada, obrigado. Vou adicioná-lo ao post.
18716
2
Assim como uma nota: Não funciona para mim no Greasemonkey 3,10
mt025
17

Estou usando o método postado por Brock Adams e até funciona no Firefox, se for iniciado pelo usuário.

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

Chamo-o pressionando o botão para que ele seja iniciado pelo usuário e ainda funcione bem usando o Chrome 35-40, o Internet Explorer 11, o Safari 7-8 e o Firefox 29-35. Testei usando a versão 8.1 do Windows e Mac OS X 10.6, 10.9 e 10.10, se isso for diferente.


Código da janela de fechamento automático (na página que se fecha)

O código completo a ser usado na janela aberta pelo usuário que pode se fechar:

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');" />

Experimente esta página de teste: (Agora testado no Chrome 40 e Firefox 35)

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


Código do abridor de janelas (em uma página que abre a página acima)

Para fazer isso funcionar, a compatibilidade entre navegadores imposta pela segurança exige que a janela a ser fechada já tenha sido aberta pelo usuário clicando em um botão no mesmo domínio do site.

Por exemplo, a janela que usa o método acima para se fechar pode ser aberta em uma página usando este código (código fornecido na minha página de exemplo vinculada acima):

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
fonte
Esqueceu as exceções iniciadas pelo usuário; boa pegada. Eu acho que a maioria dos scripts de usuários deseja uma operação totalmente automática. Eles já têm um prático mecanismo de fechamento iniciado pelo usuário - aquele pequeno X no canto superior direito. (^_^)
Brock Adams
1
De alguma forma, isso não funciona para mim. Nem no firefox 30 nem no Chrome 37. Tudo o que faz é tornar a página em branco (comportamento realmente estranho). Meu código é <button onclick="open(location,'_self').close()" >Close Window</button>. Estou fazendo algo obviamente errado? Parece-me que isso também é iniciado pelo usuário. Observe que eu obtenho o mesmo resultado se eu usar um <button>ou um <input type="button">.
LordOfThePigs
Adicionada uma página de teste acima na resposta para você.
Jeff Clayton
@YumYumYum obrigado pelo post, bitbucket.org mudou o link para bitbucket.io recentemente - fixado na resposta agora
Jeff Clayton
Funciona para mim (ter um botão na página para fechar a janela). O que não funcionou foi: window.open('', '_self', ''); window.close(); mas ele trabalhou com open(location, '_self').close();
krystonen
10

Muitas pessoas ainda estão tentando encontrar uma maneira de fechar o navegador Chrome usando javascript. O método a seguir só funciona quando você usa o Chrome como iniciador de aplicativos - quiosque por exemplo!

Eu testei o seguinte:

Estou usando a seguinte extensão: Close Kiosk

Estou seguindo as instruções de uso e parece que funciona muito bem (limpe o cache durante os testes). O javascript que eu uso é (anexado ao evento click):

window.location.href = '/closekiosk';

Espero que ajude alguém, pois é a única solução de trabalho que encontrei.

Nota: parece que a extensão é executada em segundo plano e adiciona um ícone da bandeja do Chrome. Ele tem a seguinte opção marcada: "Deixe o Chrome executar em segundo plano" (ou texto semelhante). Você pode precisar brincar com ele, até que funcione para você. Eu desmarquei e agora funciona muito bem!

Ministro
fonte
9

Apesar de pensar que é "patentemente falso", o que você diz "parece ser uma crença" está realmente correto. A documentação do Mozilla para window.close diz

Este método só pode ser chamado para janelas que foram abertas por um script usando o método window.open. Se a janela não foi aberta por um script, o seguinte erro será exibido no console do JavaScript: Os scripts podem não fechar as janelas que não foram abertas pelo script

Você diz que "ainda deve fazê-lo", mas acho que não encontrará nenhuma referência que suporte isso, talvez você tenha se lembrado de algo errado?

Gareth
fonte
9

Eu encontrei uma nova maneira que funciona perfeitamente para mim

var win = window.open("about:blank", "_self");
win.close();
Gerardo Abdo
fonte
1
este é 2017 e ainda recebo o erro de "Os scripts não podem fechar as janelas que não foram abertas pelo script".
Rotimi
Bom truque para botão de confirmação de IE 11.
Gopal00005
Funciona no Chrome e Firefox
Vineeth Pradhan
1
Este buraco parece ter sido preenchido. Não sei até o momento, mas estou usando o último dev build 84.x. A página em branco é carregada, mas o fechamento não é acionado.
Scott Christensen
4

O código abaixo funcionou para mim -

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

Testado no Chrome 43.0.2357.81

DfrDkn
fonte
Você pode adicionar sua versão do Chrome, por favor?
Stephan
Minha versão do Chrome é 43.0.2357.81.
DfrDkn
7
Para mim, isso substitui a janela atual por uma janela em / location.
usar o seguinte código
@ alianos- para mim também.
RicardoGonzales
1
Não funciona no cromo mais recente - Versão 61.0.3163.100 (Compilação oficial) (64 bits)
Subhajit
1

Isso pode ser antigo, mas vamos responder.

Eu uso top.close () para fechar uma guia. window.close () ou outro open ... close não funcionou para mim.

Soley
fonte
11
Isso também sofre com o "Scripts may not close windows that were not opened by script."problema mencionado em outras respostas.
Kad81 # 15/14
1
por favor, dê a solução em sua resposta. por favor, não discuta o problema apenas na sua resposta.
Bimal Das
0

No meu caso, a página precisava fechar, mas pode ter sido aberta por um link e, portanto window.close, falharia.

A solução que escolhi é emitir o window.close, seguido por um window.setTimeoutque redireciona para uma página diferente.

Dessa forma, se window.closefor bem-sucedida, a execução nessa página será interrompida, mas se falhar, em um segundo, será redirecionada para uma página diferente.

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

Esta resposta de Brock fez funcionar para mim. O javascript não deve ter permissão para fechar uma janela que não foi aberta pelo mesmo javascript.

Só posso fechar a janela filho se estiver a fechar a partir do javascript principal. então, em meus pais, eu posso fazer algo assim.

var myChildWindow;

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

function closeWindow() {
myChildWindow.close();
}
Crismogram
fonte
-1

Você também pode tentar usar meu código abaixo. Isso também ajudará você a redirecionar sua janela principal:

Pai:

<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" />

Aparecer:

<!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
fonte
-2

Somente se você abrir uma nova janela usando window.open (), a nova janela poderá fechar usando o código conforme mencionado acima. Isso funciona perfeitamente para mim :) Nota: Nunca use href para abrir a página em uma nova guia. Window.close () não funciona com "href". Use window.open ().

DfrDkn
fonte
1
Está apenas substituindo a janela atual. Não mais.
RicardoGonzales
-3

Eu queria compartilhar minha "solução" com esse problema. Parece que a maioria de nós está tentando fechar uma janela do navegador em uma sessão padrão, em que um usuário está visitando um site ou outro, depois de visitar outros sites e antes de visitar mais.

No entanto, minha situação é que estou criando um aplicativo Web para um dispositivo que será essencialmente a única coisa que o dispositivo faz. Você inicializa, inicia o Chrome e navega para o nosso aplicativo. Nem sequer está conectado à Internet, os servidores com os quais ele fala estão em nossos contêineres Docker locais. O usuário precisa de uma maneira de fechar o aplicativo (também conhecido como Chrome) para acessar o terminal para realizar atualizações do sistema.

Portanto, ele inicializa e lança o Chrome no modo quiosque, no endereço correto. Isso acontece para satisfazer facilmente a segunda opção na especificação:

Um contexto de navegação pode ser fechado por script se for um contexto de navegação auxiliar criado por um script (em oposição a uma ação do usuário) ou se for um contexto de navegação de nível superior cujo histórico da sessão contenha apenas um documento.

Então, simplesmente ligar window.close()do meu aplicativo de quiosque funciona !

Jonathan Tuzman
fonte
-5

Tente algo como isto onclick = "return self.close ()"

Ragven
fonte