web-dev-qa-db-fra.com

window.close et self.close ne ferment pas la fenêtre dans Chrome

Le problème est que lorsque j'appelle window.close() ou self.close(), il ne ferme pas la fenêtre. Il semble maintenant que, dans Chrome, vous ne pouvez pas fermer par script une fenêtre qui n'est pas un script créé. C’est manifestement faux, mais quoi qu’il en soit supposé, même s’il faut faire apparaître une alerte pour confirmer. Ce ne sont pas en train d'arriver.

Quelqu'un a-t-il une méthode réelle, fonctionnelle et éprouvée pour fermer une fenêtre en utilisant quelque chose comme javascript:window.close() ou javascript:self.close() qui fait exactement ce qui est attendu et qui se passe bien dans tous les navigateurs qui ne sont PAS basés sur Chrome? Toutes les suggestions seraient grandement appréciées et je suis à la recherche d'une solution spécifique à Javascript, sans implémentation de JQuery ou tierce partie. 

Mise à jour: Bien qu'une grande partie de ce qui a été suggéré présente de sérieuses limitations et problèmes d'utilisation, la dernière suggestion (spécifique à TamperMonkey) utilisant// @grant window.closedans l'en-tête du script fera souvent l'affaire, même sur les onglets normalement disponibles pas gérer la méthode proche. Bien que cela ne soit pas tout à fait idéal et ne soit pas généralisé à tous les cas, c'est une bonne solution dans mon cas.

141
GµårÐïåñ

Le javascript ordinaire ne peut pas fermer les fenêtres bon gré mal gré. Ceci est une fonctionnalité de sécurité, introduite il y a quelque temps, pour arrêter divers exploits et nuisances malveillants.

De dernière spécification de travail pour window.close() :

La méthode close() sur les objets Window doit, si toutes les conditions suivantes sont remplies, fermer le contexte de navigation A:

  • Le contexte de navigation correspondant A est pouvant être fermé par un script .
  • Le contexte de navigation du script en cours est familier avec le contexte de navigation A.
  • Le contexte de navigation du script en place est autorisé à naviguer dans le contexte de navigation A.

Un contexte de navigation est pouvant être fermé par un script s'il s'agit d'un contexte de navigation auxiliaire qui a été créé par un script (par opposition à une action de l'utilisateur), ou s'il s'agit d'un contexte de navigation dont l'historique de session ne contient qu'un seul document.

Cela signifie que, à une petite exception près, , javascript ne doit pas être autorisé à fermer une fenêtre non ouverte par le même javascript.

Chrome autorise cette exception - ce qui ne s'applique pas aux scripts utilisateur - mais pas Firefox. Les états à plat de la mise en oeuvre de Firefox :

Cette méthode ne peut être appelée que pour les fenêtres ouvertes par un script utilisant la méthode window.open.


Si vous essayez d'utiliser window.close à partir d'un Greasemonkey/Tampermonkey/userscript, vous obtiendrez:
Firefox: Le message d'erreur "Scripts may not close windows that were not opened by script."
Chrome: échoue simplement.



La solution à long terme:

La meilleure façon de traiter ce problème est de créer une extension Chrome et/ou un complément Firefox. Ceux-ci peuvent se fermer de manière fiable. la fenêtre en cours.

Cependant, étant donné que les risques de sécurité posés par window.close sont beaucoup moins importants pour un script Greasemonkey/Tampermonkey; Greasemonkey et Tampermonkey pourraient raisonnablement fournir cette fonctionnalité dans leur API (pour l’essentiel, empaqueter le travail d’extension pour vous).
Envisagez de faire une demande de fonctionnalité.



Les contournements de hacky:

Chrome  est actuellement était vulnérable à l'exploit "auto redirection". Donc, un code comme celui-ci fonctionnait en général:

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

Ceci est un comportement buggy, IMO, et est maintenant (à peu près en avril 2015) principalement bloqué. Il fonctionnera toujours à partir de injecté code uniquement si l'onglet est fraîchement ouvert et ne contient aucune page dans l'historique de navigation. Donc, ce n'est utile que dans un très petit ensemble de circonstances.

Cependant, une variante fonctionne toujours sur Chrome (v43 & v44) plus Tampermonkey (v3.11 ou version ultérieure) . Utilisez un @grant explicite et un window.close() simple. PAR EXEMPLE:

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

setTimeout (window.close, 5000);

Merci à zanet pour la mise à jour. Notez que cela ne fonctionnera pas si un seul onglet est ouvert. Il ne ferme que les onglets supplémentaires.


Firefox est sécurisé contre cet exploit. Donc, la seule façon de javascript est de paralyser les paramètres de sécurité, navigateur par navigateur.

Vous pouvez ouvrir about:config et définir
allow_scripts_to_close_windows à true.

Si votre script est destiné à un usage personnel, allez-y. Si vous demandez à quelqu'un d'autre d'activer ce paramètre, il serait intelligent, et justifié, de refuser les préjugés.

Il n'existe actuellement aucun paramètre équivalent pour Chrome.

172
Brock Adams

Chrome Correction des problèmes de sécurité sur la version 36.0.1985.125

Chrome 36.0.1985.125 MERCREDI 16 JUILLET 2014 Note de mise à jour

D'après mes observations, cette mise à jour a résolu le problème d'utilisation de window.close() pour fermer la fenêtre contextuelle. Vous verrez ceci dans la console en cas d'échec: "Les scripts ne peuvent fermer que les fenêtres ouvertes par celle-ci.". Cela signifie que Les solutions de contournement (réponse de Brock Adams) pourraient ne pas fonctionner dans la dernière version.

Ainsi, dans les versions précédentes de Chrome, le bloc de code ci-dessous peut fonctionner, mais pas avec cette mise à jour.

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

Pour cette mise à jour, vous devez mettre à jour votre code en conséquence pour fermer la fenêtre contextuelle. L’une des solutions consiste à saisir l’identifiant de la fenêtre contextuelle et à l’utiliser. 

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

méthode pour l'enlever. Vous pouvez trouver l’API des fenêtres d’extension Chrome à l’adresse chrome.windows

En fait, mon extension chrome MarkView était confrontée à ce problème et je devais mettre à jour mon code pour le faire fonctionner pour cette mise à jour Chrome. À propos, MarkView est un outil pour lire et écrire des fichiers Awesome Markdown, il fournit des fonctionnalités telles que le contour du contenu, les tableaux triables et la syntaxe du bloc de code surligné avec le numéro de ligne.

J'ai aussi créé ce post , tous les commentaires sont les bienvenus.

27
swcool

Dans Tampermonkey maintenant, vous pouvez utiliser

// @grant        window.close

Et puis simplement, appelez

window.close();
16
balping

J'utilise la méthode publiée par Brock Adams et cela fonctionne même dans Firefox, si c'est initié par l'utilisateur.

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

Je l’appelle à partir d’un bouton-poussoir, c’est donc lancé par l’utilisateur, et il fonctionne toujours correctement avec Chrome 35-40, Internet Explorer 11, Safari 7-8 et ALPHA Firefox 29-35. J'ai testé avec la version 8.1 de Windows et Mac OS X 10.6, 10.9 et 10.10 si c'est différent. 


Le code complet:

HTML:

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

JavaScript:

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

Essayez cette page de test: (maintenant testé sur Chrome 40 et Firefox 35) 

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

13
Jeff Clayton

De nombreuses personnes essaient encore de trouver un moyen de fermer le navigateur Chrome à l'aide de javascript. La méthode suivante ne fonctionne que lorsque vous utilisez Chrome comme lanceur d'APP - kiosque par exemple!

J'ai testé les éléments suivants:

J'utilise l'extension suivante: Close Kiosk

Je suis les instructions d'utilisation et cela semble bien fonctionner (assurez-vous de vider le cache pendant les tests). Le javascript que j'utilise est (attaché à l'événement click):

window.location.href = '/closekiosk';

J'espère que cela aidera quelqu'un, car c'est la seule solution efficace que j'ai trouvée.

Remarque: il semble que l'extension s'exécute en arrière-plan et ajoute une icône de barre d'état Chrome. L'option suivante est cochée: "Laisser Chrome s'exécuter en arrière-plan" (ou un texte similaire). Vous devrez peut-être jouer avec jusqu'à ce que cela fonctionne pour vous. Je l'ai décochée et maintenant ça fonctionne très bien!

9
Minister

Même si vous pensez que cela est "manifestement faux", ce que vous dites "semble être une croyance" est en fait correct. La documentation de Mozilla pour window.close dit

Cette méthode ne peut être appelée que pour les fenêtres ouvertes par un script utilisant la méthode window.open. Si la fenêtre n'a pas été ouverte par un script, le message d'erreur suivant apparaît dans la console JavaScript: Les scripts ne peuvent pas fermer les fenêtres non ouvertes par le script.

Vous dites qu'il est "supposé continuer à le faire" mais je ne pense pas que vous trouverez une référence à l'appui de cela, peut-être avez-vous mal noté quelque chose?

5
Gareth

J'ai trouvé un nouveau moyen qui fonctionne parfaitement pour moi

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

Le code ci-dessous a fonctionné pour moi -

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

Testé sur Chrome 43.0.2357.81

4
DfrDkn

Cela peut être vieux, mais répondons-y. 

J'utilise top.close () pour fermer un onglet. window.close () ou autre open ... close n'a pas fonctionné pour moi.

2
Soley

Dans mon cas, la page devait fermer, mais peut avoir été ouverte par un lien et donc window.close échouerait.

La solution que j'ai choisie est d'émettre le window.close, suivi d'un window.setTimeout qui redirige vers une autre page.

De cette façon, si window.close réussit, l'exécution sur cette page s'arrête, mais si elle échoue, elle sera redirigée dans une seconde, sur une autre page.

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