window.close e self.close non chiudono la finestra in Chrome


174

Il problema è che quando invoco window.close()o self.close()non si chiude la finestra. Ora sembra esserci la convinzione che in Chrome non è possibile chiudere tramite script qualsiasi finestra che non sia creata da script. Ciò è palesemente falso ma, a prescindere, dovrebbe comunque farlo, anche se richiede di visualizzare un avviso per confermare. Questi non stanno accadendo.

Quindi qualcuno ha un metodo reale, funzionale e comprovato per chiudere una finestra usando qualcosa di simile javascript:window.close()o javascript:self.close()che fa effettivamente ciò che è previsto e qualcosa che accade bene in ogni browser che NON è basato su Chrome? Qualsiasi suggerimento sarebbe molto apprezzato e sto cercando una soluzione specifica per Javascript, niente JQuery o implementazione di terze parti.

Aggiornamento: anche se gran parte di ciò che è stato suggerito presenta gravi limitazioni e problemi di usabilità, l'ultimo suggerimento (specifico per TamperMonkey) che utilizza // @grant window.closenell'intestazione dello script farà spesso il trucco anche su quelle schede che normalmente non sono in grado di gestire il metodo di chiusura. Sebbene non sia del tutto ideale e non generalizzato a tutti i casi, è una buona soluzione nel mio caso.


window.close()funziona per me in Chrome.
schiaccia il

3
@ GµårÐïåñ: Umm, no non lo è. Non ha nulla a che fare con la lingua. È una funzione implementata dai browser. Se riesci a scrivere un esempio minimo che mostra come window.closenon funziona come dovrebbe, penso che potrebbe essere più utile che dire "non funziona".
Blender

3
Ti ho dato DUE esempi. <a href="javascript:window.close">CLOSE</a>
Spiegazione

3
custode che è javascript improprio. Prova window.close () e funziona. window.close è solo un nome variabile e non chiamerà la funzione (almeno non lo faccio quando lo collaudo in Chrome 37). Quando cambio il tuo esempio in window.close () funziona in Chrome 37.
George,

3
GµårÐïåñ Ciò che @George ha detto NON è controverso (a meno che non abbia frainteso del tutto il significato della parola). Ha ragione nel dichiarare che hai un errore sintattico nel javascript nei tuoi esempi, e se hai lo stesso errore nel tuo codice dell'applicazione, allora questa è probabilmente la causa del tuo problema. SE, tuttavia, questi sono solo errori di battitura nei tuoi esempi, allora dovresti correggerli per ottenere risposte migliori.
Superole,

Risposte:


187

Il javascript ordinario non può chiudere Windows volenti o nolenti. Questa è una funzione di sicurezza, introdotta qualche tempo fa, per fermare vari exploit e fastidi dannosi.

Dalle ultime specifiche di lavoro perwindow.close() :

Il close()metodo sugli oggetti Window dovrebbe, se sono soddisfatte tutte le seguenti condizioni, chiudere il contesto di navigazione A :

  • Il contesto di navigazione A corrispondente è chiudibile con script .
  • Il contesto di navigazione dello script in carica abbia familiarità con il contesto di navigazione A .
  • Il contesto navigazione dello script in carica è permesso di navigare il contesto di navigazione A .

Un contesto di esplorazione può essere chiuso da script se si tratta di un contesto di esplorazione ausiliario creato da uno script (al contrario di un'azione dell'utente) o se si tratta di un contesto di esplorazione la cui cronologia delle sessioni contiene solo un documento.

Ciò significa che, con una piccola eccezione, javascript non deve poter chiudere una finestra che non è stata aperta dallo stesso javascript.

Chrome consente quell'eccezione, che non si applica agli script utente, tuttavia Firefox no. L'implementazione di Firefox flat out afferma :

Questo metodo può essere chiamato solo per le finestre che sono state aperte da uno script usando il window.openmetodo.


Se provi ad usare window.closeun Greasemonkey / Tampermonkey / userscript otterrai:
Firefox: il messaggio di errore " Scripts may not close windows that were not opened by script."
Chrome: fallisce silenziosamente.



La soluzione a lungo termine:

Il modo migliore per gestirlo è invece creare un'estensione Chrome e / o un componente aggiuntivo per Firefox. Questi possono chiudere in modo affidabile la finestra corrente.

Tuttavia, poiché i rischi per la sicurezza, posti da window.close, sono molto meno per uno script Greasemonkey / Tampermonkey; Greasemonkey e Tampermonkey potrebbero ragionevolmente fornire questa funzionalità nella loro API (essenzialmente comprimendo il lavoro dell'estensione per te).
Valuta di fare una richiesta di funzionalità.



Le soluzioni alternative hacky:

Chrome è attualmente vulnerabile all'exploit di "auto-reindirizzamento". Quindi un codice come questo funzionava in generale:

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

Si tratta di un comportamento errato, IMO, ed è ora (a partire da circa aprile 2015) per lo più bloccato. Funzionerà comunque dal codice iniettato solo se la scheda è appena aperta e non ha pagine nella cronologia di navigazione. Quindi è utile solo in una serie molto piccola di circostanze.

Tuttavia, una variante funziona ancora su Chrome (v43 e v44) più Tampermonkey (v3.11 o successive) . Usa un esplicito @grante chiaro window.close(). PER ESEMPIO:

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

setTimeout (window.close, 5000);

Grazie a zanetu per l'aggiornamento. Si noti che questo non funzionerà se è aperta una sola scheda. Chiude solo le schede aggiuntive.


Firefox è sicuro contro quell'exploit. Quindi, l'unico modo javascript è quello di paralizzare le impostazioni di sicurezza, un browser alla volta.

È possibile aprire about:confige impostare
allow_scripts_to_close_windowssu true.

Se la tua sceneggiatura è per uso personale, vai avanti e fallo. Se chiedi a qualcun altro di attivare tale impostazione, sarebbe intelligente e giustificato rifiutare con pregiudizio.

Al momento non esiste un'impostazione equivalente per Chrome.


3
Ehi amico mio, felice di sentirti finalmente. Solo una nota, su Fx puoi aggirare quella limitazione lanciando il dom.allow_scripts_to_close_windows;falseto truema immagino nulla in Chrome senza hackerare il sorgente / ricostruzione che è il modo in cui l'ho aggirato per ora. Conosco e ho parlato con lo sviluppatore di TM e nel recente alpha / beta lo abbiamo messo come opzione di compatibilità (impostazione dello script) per funzionare in stile man-in-the-middle, funziona. Immagino che a parte gli hack non abbiamo una soluzione pulita, peccato.
GµårÐïåñ

3
Se qualcuno ha problemi con window.close o la particolare differenza di comportamento tra i browser, leggi attentamente questa risposta: ha davvero tutte le informazioni giuste.
Bron Davies,

C'è un modo per verificare se la finestra è stata aperta da script o no? (Devo mostrare / nascondere un pulsante Indietro, non voglio usare l'hack) Grazie EDIT: window.opener === null
Cétia

Da Chrome 36.0.1985.125 MERCOLEDÌ, 16 LUGLIO 2014, Le soluzioni temporanee potrebbero non funzionare, dettaglio nella mia risposta.
swcool,

2
window.close()funzionerà in Tampermonkey se si imposta @grantun valore diverso da none. Vedi questa discussione .
zanetu,

32

Chrome Risolti i problemi di sicurezza nella versione 36.0.1985.125

Chrome 36.0.1985.125 MERCOLEDÌ, 16 LUGLIO 2014 Nota di rilascio

Dalla mia osservazione, questo aggiornamento ha risolto il problema relativo all'uso window.close()per chiudere la finestra popup. Lo vedrai nella console quando fallisce, "Gli script possono chiudere solo le finestre che sono state aperte da essa". Ciò significa che le soluzioni temporanee (la risposta di Brock Adams) potrebbero non funzionare nell'ultima versione.

Quindi, nelle versioni precedenti di Chrome, il blocco di codice riportato sotto potrebbe funzionare ma non con questo aggiornamento.

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

Per questo aggiornamento, è necessario aggiornare il codice di conseguenza per chiudere la finestra popup. Una delle soluzioni è quella di catturare l'id della finestra popup e utilizzarlo

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

metodo per rimuoverlo. L'API di Windows per l'estensione di Chrome è disponibile su chrome.windows .

In realtà la mia estensione Chrome MarkView stava affrontando questo problema e ho dovuto aggiornare il mio codice per farlo funzionare per questo aggiornamento di Chrome. A proposito, MarkView è lo strumento per leggere e scrivere file di markdown fantastici, fornisce funzionalità tra cui Contorno contenuto, Tabelle ordinabili e Evidenziazione della sintassi del blocco di codice con il numero di riga.

Ho anche creato questo post , tutti i commenti sono benvenuti.


2
L'hack corretto è open(location, '_self').close();- notare l'uso del valore restituito da open(). Funziona ancora su Chrome36.0.1985.125 m
Brock Adams,

Nel mio caso, ho appena provato di nuovo open(location, '_self').close();, ho ricevuto l'errore "Non autorizzato" su questo. Questo errore è diverso con 'window.close () (warning on this"Scripts may close only the windows that were opened by it."). It looked like open (location,' _self '). Close (); `spostato un po' in avanti, ma nel mio caso non può essere completato. Grazie @ brock-adams per il commento.
swcool,

Ho un dattiloscritto e quando lo metto chrome.windows.removedice che non è possibile trovare il simbolo Chrome. come posso risolvere questo? devo aggiungere una sorta di riferimento?
DevT

@devt chrome.windows.remove è l'API di estensione di Chrome, il tuo javascript dovrebbe essere riconosciuto dal tuo programma di estensione di Chrome. Puoi provarlo all'interno di background.js, nella tua estensione chrome manifest.json devi avere: "background": {"scripts": ["background.js"], ...},
swcool il

Ho rimosso la funzione di accesso MarkView per consentire agli utenti di accedere liberamente. Quindi l'esempio che ho menzionato sopra non è ora disponibile.
swcool,

21

In tampermonkey ora puoi usare

// @grant        window.close

E poi basta semplicemente chiamare

window.close();

Ho confermato che questo funziona in molti casi, ma ancora occasionali testardi ma meglio di niente, grazie. Lo aggiungerò al post.
GµårÐïåñ,

2
Proprio come una nota: non funziona per me in Greasemonkey 3.10
mt025

17

Sto usando il metodo pubblicato da Brock Adams e funziona anche in Firefox, se è stato avviato dall'utente.

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

Lo chiamo da un pulsante, quindi è avviato dall'utente e funziona ancora bene usando Chrome 35-40, Internet Explorer 11, Safari 7-8 e ANCHE Firefox 29-35. Ho testato utilizzando la versione 8.1 di Windows e Mac OS X 10.6, 10.9 e 10.10 se questo è diverso.


Codice finestra a chiusura automatica (sulla pagina che si chiude da sola)

Il codice completo da utilizzare nella finestra aperta dall'utente che può chiudersi:

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

Prova questa pagina di test: (ora testato in Chrome 40 e Firefox 35)

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


Codice apri finestra (su una pagina che apre la pagina sopra)

A tale scopo, la compatibilità cross-browser imposta dalla sicurezza richiede che la finestra che deve essere chiusa sia già stata aperta dall'utente facendo clic su un pulsante all'interno dello stesso dominio del sito.

Ad esempio, la finestra che utilizza il metodo sopra per chiudersi, può essere aperta da una pagina usando questo codice (codice fornito dalla mia pagina di esempio collegata sopra):

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

Dimenticato le eccezioni avviate dall'utente; buona pesca. Penso che la maggior parte degli utenti vogliano un funzionamento completamente automatico. Hanno già un pratico meccanismo di chiusura avviato dall'utente: quella piccola X in alto a destra. (^_^)
Brock Adams,

1
In qualche modo, questo non funziona per me. Né su Firefox 30 né su Chrome 37. Tutto ciò che fa è rendere la pagina vuota (comportamento davvero strano). Il mio codice è <button onclick="open(location,'_self').close()" >Close Window</button>. Sto facendo qualcosa di ovviamente sbagliato? Mi sembra che anche questo sia avviato dall'utente. Nota che ottengo lo stesso risultato se uso a <button>o an <input type="button">.
LordOfThePigs,

Aggiunta una pagina di prova sopra nella risposta per te.
Jeff Clayton,

@YumYumYum grazie per il post, bitbucket.org ha cambiato il link a bitbucket.io di recente - risolto nella risposta ora
Jeff Clayton

Funziona per me (avere un pulsante sulla pagina per chiudere la finestra). Ciò che non ha funzionato è stato: window.open('', '_self', ''); window.close(); ma ha funzionato con open(location, '_self').close();
krystonen,

10

Molte persone stanno ancora cercando di trovare un modo per chiudere il browser Chrome utilizzando javascript. Il seguente metodo funziona solo quando usi Chrome come lanciatore di APP, ad esempio il chiosco multimediale!

Ho testato quanto segue:

Sto usando la seguente estensione: Close Kiosk

Sto seguendo le istruzioni per l'uso e sembra funzionare bene (assicurati di svuotare la cache mentre esegui i test). Il javascript che uso è (allegato all'evento click):

window.location.href = '/closekiosk';

Spero che ciò aiuti qualcuno, poiché è l'unica soluzione funzionante che ho trovato.

Nota: sembra che l'estensione venga eseguita in background e aggiunge un'icona nella barra di Chrome. È selezionata la seguente opzione: "Esegui Chrome in background" (o testo simile). Potrebbe essere necessario giocarci fino a quando non funziona per te. L'ho deselezionato e ora funziona bene!


9

Nonostante pensi che sia "palesemente falso", ciò che dici "sembra essere una convinzione" è in realtà corretto. La documentazione di Mozilla per window.close dice

Questo metodo può essere chiamato solo per le finestre che sono state aperte da uno script usando il metodo window.open. Se la finestra non è stata aperta da uno script, nella console JavaScript viene visualizzato il seguente errore: Gli script potrebbero non chiudere le finestre che non sono state aperte dallo script

Dici che si suppone che "lo faccia ancora" ma non penso che troverai alcun riferimento a sostegno di ciò, forse hai dimenticato qualcosa?


9

Ho trovato un nuovo modo che funziona perfettamente per me

var win = window.open("about:blank", "_self");
win.close();

1
questo è il 2017 e ho ancora l'errore "Gli script potrebbero non chiudere le finestre che non sono state aperte dallo script".
Rotimi

Bello hack per il pulsante di conferma di IE 11.
Gopal00005

Funziona su Chrome e Firefox
Vineeth Pradhan,

1
Questo buco sembra essere stato riempito. Non so da quando, ma sto usando l'ultimo sviluppo build 84.x. La pagina vuota viene caricata ma la chiusura non si attiva.
Scott Christensen,

4

Il codice seguente ha funzionato per me -

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

Testato su Chrome 43.0.2357.81


Puoi aggiungere la tua versione di Chrome per favore?
Stephan,

La mia versione di Chrome è 43.0.2357.81.
DfrDkn,

7
Per me questo sostituisce solo la finestra corrente, con una finestra in / posizione.
alianos-

@ alianos- anche per me.
RicardoGonzales,

1
Non funziona nell'ultima versione di Chrome - Versione 61.0.3163.100 (build ufficiale) (64 bit)
Subhajit

1

Potrebbe essere vecchio, ma rispondiamo.

Uso top.close () per chiudere una scheda. window.close () o altro open ... close non ha funzionato per me.


11
Ciò soffre anche del "Scripts may not close windows that were not opened by script."problema menzionato in altre risposte.
kad81,

1
per favore, dai una soluzione alla tua risposta. per favore non discutere il problema solo sulla tua risposta.
Bimal Das,

0

Nel mio caso, la pagina doveva chiudersi, ma potrebbe essere stata aperta da un collegamento e quindi window.closenon avrebbe funzionato.

La soluzione che ho scelto è emettere il window.close, seguito da un window.setTimeoutche reindirizza a una pagina diversa.

In questo modo, se window.closeriesce, l'esecuzione su quella pagina si interrompe, ma se fallisce, in un secondo, reindirizzerà a una pagina diversa.

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

0

Questa risposta di Brock ha funzionato per me. javascript non deve poter chiudere una finestra che non è stata aperta dallo stesso javascript.

Posso chiudere la finestra figlio solo se lo chiuderò dal javascript principale. quindi nel mio genitore posso fare qualcosa del genere.

var myChildWindow;

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

function closeWindow() {
myChildWindow.close();
}

-1

Puoi anche provare a usare il mio codice qui sotto. Questo ti aiuterà anche a reindirizzare la finestra principale:

Genitore:

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

Apparire:

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


-2

Solo se apri una nuova finestra usando window.open () la nuova finestra sarà in grado di chiudere usando il codice come ho menzionato sopra. Per me funziona perfettamente :) Nota: non utilizzare mai href per aprire la pagina in una nuova scheda. Window.close () non funziona con "href". Utilizzare invece window.open ().


1
Sta solo sostituendo la finestra di curren. Non piu.
RicardoGonzales,

-3

Volevo condividere la mia "soluzione" con questo problema. Sembra che la maggior parte di noi stia provando a chiudere una finestra del browser in una sessione del browser standard, in cui un utente visita un sito Web o un altro, dopo aver visitato altri siti Web e prima di visitarne altri.

Tuttavia, la mia situazione è che sto creando un'app Web per un dispositivo che sarà essenzialmente l'unica cosa che il dispositivo fa. Lo avvii, avvia Chrome e passa alla nostra app. Non è nemmeno connesso a Internet, tutti i server con cui parla si trovano nei nostri contenitori Docker locali. L'utente ha bisogno di un modo per chiudere l'app (ovvero chiudere Chrome) in modo da poter accedere al terminale per eseguire gli aggiornamenti di sistema.

Quindi si avvia, avvia Chrome in modalità kiosk, già all'indirizzo corretto. Questo accade per soddisfare facilmente la seconda opzione nelle specifiche:

Un contesto di esplorazione può essere chiuso da script se si tratta di un contesto di esplorazione ausiliario creato da uno script (a differenza di un'azione dell'utente) o se si tratta di un contesto di esplorazione di livello superiore la cui cronologia delle sessioni contiene solo un documento.

Quindi semplicemente chiamare window.close()dalla mia app kiosk funziona e basta !


-5

Prova qualcosa del genere onclick = "return self.close ()"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.