window.close und self.close schließen das Fenster in Chrome nicht

174

Das Problem ist, dass wenn ich aufrufe window.close()oder self.close()es das Fenster nicht schließt. Nun scheint es eine Überzeugung zu geben, dass Sie in Chrome kein Fenster schließen können, das nicht per Skript erstellt wurde. Das ist offensichtlich falsch, aber unabhängig davon, ob es dies dennoch tun soll, selbst wenn zur Bestätigung eine Warnung angezeigt werden muss. Diese passieren nicht.

So hat jemand wirklich, funktionale und bewährtes Verfahren zur Herstellung ein Fenster zu schließen etwas mit wie javascript:window.close()oder javascript:self.close()dass tatsächlich tut , was erwartet wird , und etwas , das ganz gut in jedem Browser geschieht , das Chrome basiert nicht? Alle Vorschläge würden sehr geschätzt und ich suche nach Javascript-spezifischer Lösung, nichts JQuery oder Implementierung durch Dritte.

Update: Während vieles, was vorgeschlagen wurde, schwerwiegende Einschränkungen und Usability-Probleme aufweist, reicht der neueste Vorschlag (speziell für TamperMonkey), der // @grant window.closeim Skript-Header verwendet wird, häufig auch auf Registerkarten aus, die normalerweise nicht mit der Methode close umgehen können. Obwohl es nicht ganz ideal ist und nicht auf jeden Fall verallgemeinert wird, ist es in meinem Fall eine gute Lösung.

GµårÐïåñ
quelle
window.close()arbeitet für mich in Chrom.
Brei
3
@ GµårÐïåñ: Ähm, nein, ist es nicht. Es hat nichts mit der Sprache zu tun. Es ist eine Funktion, die von Browsern implementiert wird. Wenn Sie ein minimales Beispiel schreiben können, das zeigt, wie window.closees nicht so funktioniert, wie es sollte, kann dies hilfreicher sein, als zu sagen: "Es funktioniert nicht".
Blender
3
Ich habe Ihnen zwei Beispiele gegeben. Rechtschreibung für Sie,<a href="javascript:window.close">CLOSE</a>
GµårÐïåñ
3
Wächter, der falsches Javascript ist. Versuchen Sie window.close () und es funktioniert. window.close ist nur ein Variablenname und ruft die Funktion nicht auf (zumindest nicht, wenn ich sie in Chrome 37 teste). Wenn ich Ihr Beispiel in window.close () ändere, funktioniert es in Chrome 37.
George
3
GµårÐïåñ Was @George gesagt hat, ist NICHT umstritten (es sei denn, ich habe die Bedeutung des Wortes völlig falsch verstanden). Er gibt zu Recht an, dass Sie in Ihren Beispielen einen syntaktischen Fehler im Javascript haben, und wenn Sie denselben Fehler in Ihrem Anwendungscode haben, ist dies höchstwahrscheinlich die Ursache für Ihr Problem. WENN dies jedoch nur Tippfehler in Ihren Beispielen sind, sollten Sie diese Tippfehler korrigieren, um bessere Antworten zu erhalten.
Superole

Antworten:

187

Gewöhnliches Javascript kann Fenster nicht ohne weiteres schließen. Dies ist eine Sicherheitsfunktion, die vor einiger Zeit eingeführt wurde, um verschiedene böswillige Exploits und Belästigungen zu stoppen.

Aus der neuesten Arbeitsspezifikation fürwindow.close() :

Die close()Methode für Fensterobjekte sollte, wenn alle folgenden Bedingungen erfüllt sind, den Browserkontext A schließen :

  • Der entsprechende Browser - Kontext A ist Skript verschließbar .
  • Der Browserkontext des etablierten Skripts ist mit dem Browserkontext A vertraut .
  • Der Browserkontext des etablierten Skripts darf im Browserkontext A navigieren .

Ein Browser - Kontext ist Skript verschließbare wenn es ein Hilfs Browsing Kontext ist , die durch ein Skript erstellt wurde (wie durch eine Aktion des Benutzers im Gegensatz zu), oder wenn es sich um einen Browser - Kontext , dessen Sitzungsverlaufes enthält nur ein Dokument.

Dies bedeutet, dass Javascript mit einer kleinen Ausnahme kein Fenster schließen darf, das nicht von demselben Javascript geöffnet wurde.

Chrome lässt diese Ausnahme zu, die nicht für Benutzerskripte gilt, Firefox jedoch nicht. In der Firefox-Implementierung heißt es :

Diese Methode darf nur für Fenster aufgerufen werden, die von einem Skript mit der window.openMethode geöffnet wurden .


Wenn Sie versuchen, window.closeein Greasemonkey / Tampermonkey / Userscript zu verwenden, erhalten Sie Folgendes:
Firefox: Die Fehlermeldung " Scripts may not close windows that were not opened by script."
Chrome: schlägt nur stillschweigend fehl.



Die langfristige Lösung:

Der beste Weg, um damit umzugehen, besteht darin , stattdessen eine Chrome-Erweiterung und / oder ein Firefox-Add-On zu erstellen. Diese können das aktuelle Fenster zuverlässig schließen.

Da die Sicherheitsrisiken window.closefür ein Greasemonkey / Tampermonkey-Skript jedoch viel geringer sind; Greasemonkey und Tampermonkey könnten diese Funktionalität in ihrer API vernünftigerweise bereitstellen (im Wesentlichen die Erweiterungsarbeit für Sie verpacken).
Erwägen Sie, eine Funktionsanforderung zu stellen.



Die hackigen Problemumgehungen:

Chrome war derzeit anfällig für den Exploit "Selbstumleitung". Code wie dieser funktionierte also im Allgemeinen:

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

Dies ist ein fehlerhaftes Verhalten, IMO, und ist jetzt (ab ungefähr April 2015) größtenteils blockiert. Es funktioniert nur dann mit injiziertem Code , wenn die Registerkarte neu geöffnet wurde und keine Seiten im Browserverlauf enthalten sind. Es ist also nur unter sehr kleinen Umständen nützlich.

Eine Variante funktioniert jedoch weiterhin unter Chrome (v43 & v44) plus Tampermonkey (v3.11 oder höher) . Verwenden Sie eine explizite @grantund einfache window.close(). Z.B:

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

setTimeout (window.close, 5000);

Danke an zanetu für das Update. Beachten Sie, dass dies nicht funktioniert, wenn nur eine Registerkarte geöffnet ist. Es werden nur zusätzliche Registerkarten geschlossen.


Firefox ist gegen diesen Exploit sicher. Die einzige Möglichkeit, Javascript zu verwenden, besteht darin, die Sicherheitseinstellungen Browser für Browser zu lähmen.

Sie können öffnen about:configund einstellen
allow_scripts_to_close_windowsauf true.

Wenn Ihr Skript für den persönlichen Gebrauch bestimmt ist, machen Sie das. Wenn Sie jemanden bitten, diese Einstellung zu aktivieren, wäre er klug und gerechtfertigt, mit Vorurteilen abzulehnen.

Derzeit gibt es keine entsprechende Einstellung für Chrome.

Brock Adams
quelle
3
Hey mein Freund, ich bin froh endlich von dir zu hören. Nur eine Anmerkung, bei Fx können Sie diese Einschränkung umgehen, indem Sie das auf umdrehen dom.allow_scripts_to_close_windows;false, trueaber ich denke nichts in Chrome, ohne die Quelle zu hacken / neu zu erstellen, so habe ich es vorerst umgangen . Ich kenne und habe mit dem TM-Entwickler gesprochen und in der jüngsten Alpha / Beta-Version haben wir es als Kompatibilitätsoption (Einstellung des Skripts) eingeführt, um im Man-in-the-Middle-Stil ausgeführt zu werden. Ich denke, kurz vor den Hacks haben wir keine saubere Lösung, schade.
GµårÐïåñ
3
Wenn jemand Probleme mit window.close oder dem besonderen Verhaltensunterschied zwischen Browsern hat, lesen Sie diese Antwort sehr sorgfältig durch - sie enthält wirklich die richtigen Informationen.
Bron Davies
Gibt es eine Möglichkeit zu überprüfen, ob das Fenster per Skript geöffnet wurde oder nicht? (Ich muss einen Zurück-Button ein- / ausblenden, ich möchte den Hack nicht verwenden.) Danke BEARBEITEN: window.opener === null
Cétia
Seit Chrome 36.0.1985.125 MITTWOCH, 16. JULI 2014, funktionieren die hackigen Problemumgehungen möglicherweise nicht, Einzelheiten in meiner Antwort.
swcool
2
window.close()funktioniert in Tampermonkey, wenn Sie @granteinen anderen Wert als festlegen none. Siehe diesen Thread .
Zanetu
32

Chrome Die Sicherheitsprobleme in Version 36.0.1985.125 wurden behoben

Chrome 36.0.1985.125 MITTWOCH, 16. Juli 2014 Freigabevermerk

Meiner Beobachtung nach hat dieses Update das Problem beim window.close()Schließen des Popup-Fensters behoben . Sie sehen dies in der Konsole, wenn es fehlschlägt: "Skripte schließen möglicherweise nur die Fenster, die von ihr geöffnet wurden." Das bedeutet, dass die hackigen Problemumgehungen (Brock Adams 'Antwort) in der neuesten Version möglicherweise nicht funktionieren .

In den vorherigen von Chrome veröffentlichten Builds hat der folgende Codeblock möglicherweise funktioniert, jedoch nicht mit diesem Update.

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

Für dieses Update müssen Sie Ihren Code entsprechend aktualisieren, um das Popup-Fenster zu schließen. Eine der Lösungen besteht darin, die Popup-Fenster-ID abzurufen und zu verwenden

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

Methode, um es zu entfernen. Die Chrome-Erweiterungsfenster-API finden Sie unter chrome.windows .

Tatsächlich war meine Chrome-Erweiterung MarkView mit diesem Problem konfrontiert und ich musste meinen Code aktualisieren, damit er für dieses Chrome-Update funktioniert. MarkView ist übrigens ein Tool zum Lesen und Schreiben von Awesome Markdown-Dateien. Es bietet Funktionen wie Inhaltsübersicht, sortierbare Tabellen und Codeblock-Syntax-Highlight mit Zeilennummer.

Ich habe auch diesen Beitrag erstellt , Kommentare sind willkommen.

swcool
quelle
2
Der richtige Hack ist open(location, '_self').close();- beachten Sie die Verwendung des Rückgabewerts von open(). Dies funktioniert immer noch auf Chrome36.0.1985.125 m
Brock Adams
In meinem Fall teste ich einfach noch einmal mit open(location, '_self').close();, ich habe den Fehler "Nicht autorisiert" erhalten. Dieser Fehler ist anders bei 'window.close () (warning on this"Scripts may close only the windows that were opened by it."). It looked like open (location,' _self '). Close (); `ist ein wenig vorwärts gegangen, kann aber in meinem Fall nicht abgeschlossen werden. Danke @ brock-adams für den Kommentar.
swcool
Ich habe Typoskript und wenn ich chrome.windows.removees sage, heißt es, dass ich kein Symbolchrom finden konnte. Wie kann ich das beheben? Muss ich eine Referenz hinzufügen?
DevT
@devt chrome.windows.remove ist die Chrome-Erweiterungs-API. Ihr Javascript sollte von Ihrem Chrome-Erweiterungsprogramm erkannt werden. Sie können es in background.js versuchen. In Ihrer Chrome-Erweiterung manifest.json benötigen Sie: "background": {"scripts": ["background.js"], ...},
swcool
Ich hatte die MarkView- Anmeldefunktion entfernt, damit Benutzer frei darauf zugreifen können. Das oben erwähnte Beispiel ist jetzt nicht verfügbar.
swcool
21

In Tampermonkey können Sie jetzt verwenden

// @grant        window.close

Und dann einfach anrufen

window.close();
balping
quelle
Ich habe bestätigt, dass dies in vielen Fällen funktioniert, aber gelegentlich immer noch hartnäckig, aber besser als nichts, danke. Ich werde es dem Beitrag hinzufügen.
GµårÐïåñ
2
Nur als Hinweis: Ich arbeite nicht für mich in Greasemonkey 3.10
mt025
17

Ich verwende die von Brock Adams veröffentlichte Methode und sie funktioniert sogar in Firefox, wenn sie vom Benutzer initiiert wurde.

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

Ich rufe es per Tastendruck auf, damit es vom Benutzer initiiert wird , und es funktioniert immer noch einwandfrei mit Chrome 35-40, Internet Explorer 11, Safari 7-8 und AUCH Firefox 29-35. Ich habe mit Version 8.1 von Windows und Mac OS X 10.6, 10.9 und 10.10 getestet, ob dies anders ist.


Code des selbstschließenden Fensters (auf der Seite, die sich selbst schließt)

Der vollständige Code für das vom Benutzer geöffnete Fenster, das sich selbst schließen kann:

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

Probieren Sie diese Testseite aus: (Jetzt in Chrome 40 und Firefox 35 getestet)

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


Fensteröffnercode (auf einer Seite, die die obige Seite öffnet)

Damit dies funktioniert, erfordert die sicherheitsübergreifende Cross-Browser-Kompatibilität, dass das zu schließende Fenster bereits vom Benutzer geöffnet wurde, der auf eine Schaltfläche innerhalb derselben Site-Domain klickt.

Zum Beispiel kann das Fenster, das die obige Methode verwendet, um sich selbst zu schließen, von einer Seite mit diesem Code geöffnet werden (Code von meiner oben verlinkten Beispielseite):

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
quelle
Ich habe die vom Benutzer eingeleiteten Ausnahmen vergessen. guter Fang. Ich denke, die meisten Anwender wollen einen vollautomatischen Betrieb. Sie haben bereits einen praktischen, vom Benutzer initiierten Schließmechanismus - das kleine X oben rechts. (^_^)
Brock Adams
1
Irgendwie funktioniert das bei mir nicht. Weder unter Firefox 30 noch unter Chrome 37. Die Seite wird nur leer (wirklich seltsames Verhalten). Mein Code ist <button onclick="open(location,'_self').close()" >Close Window</button>. Mache ich etwas offensichtlich falsch? Es scheint mir, dass dies auch vom Benutzer initiiert wird. Beachten Sie, dass ich das gleiche Ergebnis erhalte, wenn ich ein <button>oder ein verwende <input type="button">.
LordOfThePigs
Oben in der Antwort wurde eine Testseite für Sie hinzugefügt.
Jeff Clayton
@YumYumYum danke für den Beitrag, bitbucket.org hat den Link zu bitbucket.io kürzlich geändert - in der Antwort jetzt behoben
Jeff Clayton
Es funktioniert für mich (mit einer Schaltfläche auf der Seite, um das Fenster zu schließen). Was nicht funktionierte war: window.open('', '_self', ''); window.close(); aber es funktionierte mit open(location, '_self').close();
krystonen
10

Viele Leute versuchen immer noch, den Chrome-Browser mit Javascript zu schließen. Die folgende Methode funktioniert nur, wenn Sie Chrome als APP-Launcher verwenden - zum Beispiel Kiosk!

Ich habe folgendes getestet:

Ich verwende die folgende Erweiterung: Kiosk schließen

Ich folge den Gebrauchsanweisungen und es scheint gut zu funktionieren (stellen Sie sicher, dass Sie den Cache leeren, während Sie die Tests durchführen). Das von mir verwendete Javascript ist (an das Klickereignis angehängt):

window.location.href = '/closekiosk';

Ich hoffe, das hilft jemandem, da es die einzige funktionierende Lösung ist, die ich gefunden habe.

Hinweis: Die Erweiterung wird anscheinend im Hintergrund ausgeführt und fügt ein Chrome-Taskleistensymbol hinzu. Die folgende Option ist aktiviert: "Chrome im Hintergrund laufen lassen" (oder ähnlicher Text). Möglicherweise müssen Sie damit spielen, bis es für Sie funktioniert. Ich habe es deaktiviert und jetzt funktioniert es einwandfrei!

Minister
quelle
9

Obwohl Sie denken, es sei "offensichtlich falsch", ist das, was Sie sagen "scheint ein Glaube zu sein", tatsächlich richtig. In der Mozilla-Dokumentation für window.close heißt es

Diese Methode darf nur für Fenster aufgerufen werden, die von einem Skript mit der window.open-Methode geöffnet wurden. Wenn das Fenster nicht von einem Skript geöffnet wurde, wird in der JavaScript-Konsole der folgende Fehler angezeigt: Skripte schließen möglicherweise keine Fenster, die nicht vom Skript geöffnet wurden

Sie sagen, dass es "es immer noch tun soll", aber ich glaube nicht, dass Sie eine Referenz finden werden, die dies unterstützt. Vielleicht haben Sie sich an etwas falsch erinnert?

Gareth
quelle
9

Ich habe einen neuen Weg gefunden, der perfekt für mich funktioniert

var win = window.open("about:blank", "_self");
win.close();
Gerardo Abdo
quelle
1
Dies ist 2017 und ich erhalte immer noch die Fehlermeldung "Skripte schließen möglicherweise keine Fenster, die nicht per Skript geöffnet wurden."
Rotimi
Netter Hack für Bestätigungsknopf von IE 11.
Gopal00005
Funktioniert auf Chrome und Firefox
Vineeth Pradhan
1
Dieses Loch scheint gefüllt worden zu sein. Ich weiß nicht wann, aber ich verwende den neuesten Entwickler Build 84.x. Die leere Seite wird geladen, aber das Schließen wird nicht ausgelöst.
Scott Christensen
4

Der folgende Code hat bei mir funktioniert -

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

Getestet auf Chrome 43.0.2357.81

DfrDkn
quelle
Können Sie bitte Ihre Chrome-Version hinzufügen?
Stephan
Meine Chrome-Version ist 43.0.2357.81.
DfrDkn
7
Für mich ersetzt das nur das aktuelle Fenster durch ein Fenster an / location.
Alianos
@ alianos- auch für mich.
RicardoGonzales
1
Funktioniert nicht in neuestem Chrome - Version 61.0.3163.100 (Official Build) (64-Bit)
Subhajit
1

Das mag alt sein, aber lassen Sie es uns beantworten.

Ich benutze top.close () , um einen Tab zu schließen. window.close () oder ein anderes Öffnen ... Schließen hat bei mir nicht funktioniert.

Soley
quelle
11
Dies leidet auch unter dem "Scripts may not close windows that were not opened by script."in anderen Antworten erwähnten Problem.
Kad81
1
Bitte geben Sie eine Lösung für Ihre Antwort. Bitte besprechen Sie das Problem nicht nur anhand Ihrer Antwort.
Bimal Das
0

In meinem Fall musste die Seite geschlossen werden, wurde jedoch möglicherweise über einen Link geöffnet und window.closeschlägt daher fehl.

Die Lösung, die ich gewählt habe, ist die Ausgabe der window.close, gefolgt von einer window.setTimeout, die auf eine andere Seite umleitet.

Wenn dies window.closeerfolgreich ist, wird die Ausführung auf dieser Seite gestoppt. Wenn dies jedoch fehlschlägt, wird sie in einer Sekunde auf eine andere Seite umgeleitet.

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

Diese Antwort von Brock bringt es für mich zum Laufen. Javascript darf kein Fenster schließen, das nicht von demselben Javascript geöffnet wurde.

Ich kann das untergeordnete Fenster nur schließen, wenn ich es über das übergeordnete Javascript schließen werde. Also kann ich bei meinen Eltern so etwas tun.

var myChildWindow;

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

function closeWindow() {
myChildWindow.close();
}
Crismogramm
quelle
-1

Sie können auch versuchen, meinen Code unten zu verwenden. Dies hilft Ihnen auch dabei, Ihr übergeordnetes Fenster umzuleiten:

Elternteil:

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

Aufpoppen:

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

Nur wenn Sie ein neues Fenster mit window.open () öffnen, kann das neue Fenster mit Code geschlossen werden, wie oben erwähnt. Dies funktioniert perfekt für mich :) Hinweis: Verwenden Sie niemals href, um die Seite in einem neuen Tab zu öffnen. Window.close () funktioniert nicht mit "href". Verwenden Sie stattdessen window.open ().

DfrDkn
quelle
1
Es ersetzt nur das aktuelle Fenster. Nicht mehr.
RicardoGonzales
-3

Ich wollte meine "Lösung" mit diesem Problem teilen. Es scheint, als würden die meisten von uns versuchen, ein Browserfenster in einer Standardbrowsersitzung zu schließen, in der ein Benutzer die eine oder andere Website besucht, nachdem er andere Websites besucht hat und bevor er weitere besucht.

Meine Situation ist jedoch, dass ich eine Web-App für ein Gerät erstelle, die im Wesentlichen das einzige ist, was das Gerät tut. Sie starten es, es startet Chrome und navigiert zu unserer App. Es ist nicht einmal mit dem Internet verbunden, alle Server, mit denen es spricht, befinden sich in unseren lokalen Docker-Containern. Der Benutzer benötigt eine Möglichkeit, die App zu schließen (auch bekannt als Chrome schließen), damit er auf das Terminal zugreifen kann, um Systemaktualisierungen durchzuführen.

Also bootet es, startet Chrome im Kiosk-Modus, bereits an der richtigen Adresse. Dies erfüllt leicht die zweite Option in der Spezifikation:

Ein Browserkontext kann per Skript geschlossen werden, wenn es sich um einen zusätzlichen Browserkontext handelt, der von einem Skript erstellt wurde (im Gegensatz zu einer Aktion des Benutzers), oder wenn es sich um einen Browserkontext der obersten Ebene handelt, dessen Sitzungsverlauf nur ein Dokument enthält.

Es funktioniert also einfach, einfach window.close()von meiner Kiosk-App aus anzurufen !

Jonathan Tuzman
quelle
-5

Versuchen Sie so etwas onclick = "return self.close ()"

Ragven
quelle