window.closeとself.closeがChromeのウィンドウを閉じない


174

問題は、起動したとき、window.close()またはself.close()ウィンドウが閉じないときです。現在、Chromeではスクリプトで作成されていないウィンドウをスクリプトで閉じることができないという考えがあるようです。これは明らかに誤りですが、確認のために警告をポップアップ表示する必要がある場合でも、それを実行することになっています。これらは起こっていません。

だから、誰もが同じようなものを使用して、ウィンドウを閉じるの本当の、機能的では実績のある方法持っているjavascript:window.close()か、javascript:self.close()実際に何が期待されているかいとChromeをベースにしていないすべてのブラウザでうまく起こる何かということを?任意の提案をいただければ幸いです。私はJavaScript固有のソリューションを探しています。JQueryやサードパーティの実装は必要ありません。

更新:提案されているものの多くには深刻な制限と使いやすさの問題// @grant window.closeがありますが、スクリプトヘッダーで使用する最新の提案(TamperMonkeyに固有)は、通常はcloseメソッドを処理できないタブでもうまく機能します。完全に理想的ではなく、すべてのケースに一般化されているわけではありませんが、それは私の場合には良い解決策です。


window.close()Chromeで動作します。
2013年

3
@ GµårÐïåñ:うーん、違います。言語とは何の関係もありません。ブラウザが実装している機能です。どのようにwindow.close動作しないのかを示す最小限の例を書くことができれば、「動作しない」と言うよりも役立つと思います。
Blender 2013年

3
2つの例を挙げました。スペルをお伝えします<a href="javascript:window.close">CLOSE</a>
GµårÐïåñ 2013年

3
不適切なJavaScriptであるガーディアン。window.close()を試してみてください。window.closeは単なる変数名であり、関数を呼び出しません(少なくとも、Chrome 37でテストした場合は呼び出しません)。私はそれがクロム37で動作します)(window.closeをするためにあなたの例を変更する場合
ジョージ

3
GµårÐïåñ @Georgeが言ったことは意味がない(私が単語の意味を完全に誤解していない限り)。彼はあなたの例のJavaScriptに構文エラーがあると述べているのは正しいです、そしてあなたがあなたのアプリケーションコードに同じエラーがあるなら、これはおそらく問題の原因です。ただし、これらが例のタイプミスにすぎない場合は、それらのタイプミスを修正して、より適切な回答を得る必要があります。
スーパーロール、2015

回答:


187

通常のJavaScriptは、ウィンドウを完全に閉じることはできません。これは、しばらく前に導入されたセキュリティ機能であり、さまざまな悪意のある悪用や迷惑行為を阻止します。

以下からの最新の作業仕様window.close()

close()Windowオブジェクトのメソッドは、以下の条件がすべて満たされた場合、ブラウジングコンテキストAを閉じる必要があります。

  • 対応するブラウジングコンテキストAは、スクリプトで閉じることができます。
  • 現在のスクリプトのブラウジングコンテキストは、ブラウジングコンテキストAに精通しています。
  • 現在のスクリプトのブラウジングコンテキストは、ブラウジングコンテキストAをナビゲートできます。

ブラウジングコンテキストは(ユーザーのアクションではなく)スクリプトによって作成された補助ブラウジングコンテキストである場合、またはセッション履歴に1つのドキュメントのみが含まれるブラウジングコンテキストである場合、スクリプトで閉じることができます。

つまり、1つの小さな例外を除いて、同じJavaScriptで開かれていないウィンドウをJavaScriptで閉じることは許可されません。

Chromeはその例外を許可しますが、これはユーザースクリプトには適用されませんが、Firefoxは許可されません。 Firefoxの実装はフラットアウト状態です:

このメソッドは、このメソッドを使用するスクリプトによって開かれたウィンドウに対してのみ呼び出すことができますwindow.open


window.closeGreasemonkey / Tampermonkey / userscript から使用しようとすると、
Firefox:エラーメッセージ " Scripts may not close windows that were not opened by script."
Chrome:静かに失敗します。



長期的な解決策:

これに対処する最良の方法は、代わりにChrome拡張機能やFirefoxアドオンを作成することです。 これらは、現在のウィンドウを確実に閉じることができます。

ただし、によって引き起こされるセキュリティリスクwindow.closeは、Greasemonkey / Tampermonkeyスクリプトの方がはるかに少ないためです。GreasemonkeyとTampermonkeyは、APIでこの機能を合理的に提供できます(基本的に、拡張機能の作業をパッケージ化します)。
機能のリクエストを検討してください。



ハックな回避策:

Chrome は現在、「自己リダイレクト」エクスプロイトに対して脆弱でした。したがって、このようなコードは一般的に機能していました:

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

これはバグのある動作であるIMOであり、現在(およそ2015年4月の時点で)ほとんどブロックされています。タブが新しく開かれ、閲覧履歴にページがない場合にのみ挿入されたコードから機能します。そのため、ごく一部の状況でのみ役立ちます。

ただし、バリエーションはChrome(v43およびv44)とTampermonkey(v3.11以降)で引き続き機能します。明示的@grantでプレーンなを使用してくださいwindow.close()。例えば:

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

setTimeout (window.close, 5000);

更新してくれたzanetuに感謝します。開いているタブが1つしかない場合、これは機能しません。追加のタブを閉じるだけです。


Firefoxはそのエクスプロイトに対して安全です。したがって、JavaScriptの唯一の方法は、一度に1つのブラウザでセキュリティ設定を無効にすることです。

あなたは開くことができますabout:configし、設定
allow_scripts_to_close_windowsしますtrue

スクリプトが個人用である場合は、先に進んでください。他の誰かにその設定をオンにするように頼むと、彼らは賢く、正当化されて、偏見をもって拒否するでしょう。

現在、Chromeに相当する設定はありません。


3
やあ、私の友人、ようやくあなたから連絡をくれてうれしい。ただ注意してください、Fxではdom.allow_scripts_to_close_windows;falsetoをフリップすることでその制限を回避できますがtrue、Chromeではソース/再構築をハックしないと何も起こらないと思います。これが今のところ回避策です。私はTM開発者と知り、話し合いました。最近のアルファ/ベータでは、中間者スタイルで動作する互換性オプション(スクリプトの設定)として動作します。残念なことに、私たちにはクリーンなソリューションがないハックが不足しています。
GµårÐïåñ 2013年

3
誰かがwindow.closeやブラウザ間の特定の動作の違いで問題を抱えている場合は、この回答を注意深く読んでください。本当に正しい情報がすべて含まれています。
Bron Davies 14

ウィンドウがスクリプトによって開かれたかどうかを確認する方法はありますか?いるwindow.opener ===ヌル:ありがとうEDIT(私はハックを使用したくない、戻るボタンを表示/非表示する必要があります)
Cétia

Chrome 36.0.1985.125 2014年7月16日水曜日以降、ハックの回避策が機能しない可能性があります。詳細は私の回答に記載されています。
swcool 2014

2
window.close()@grant以外の値に設定すると、Tampermonkeyで動作しますnoneこのスレッドを参照してください。
zanetu 2015

32

Chromeはバージョン36.0.1985.125のセキュリティ問題を修正しました

Chrome 36.0.1985.125水曜日、2014年7月16日 リリースノート

私の観察によると、このアップデートwindow.close()はポップアップウィンドウを閉じるためにを使用する際の問題を修正しました。失敗すると、コンソールに「スクリプトは、開いたウィンドウのみを閉じる可能性があります。」と表示されます。つまり、ハックの回避策(Brock Adamsの回答)最新のリリースでは機能ない可能性があります。

そのため、以前のChromeリリースビルドでは、以下のコードブロックは機能する可能性がありますが、このアップデートでは機能しません。

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

この更新では、ポップアップウィンドウを閉じるために、それに応じてコードを更新する必要があります。解決策の1つは、ポップアップウィンドウIDを取得して使用することです。

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

それを削除するメソッド。Chrome拡張ウィンドウAPIはchrome.windowsにあります

実際、Chromeの拡張機能MarkViewがこの問題に直面しており、このChrome Updateで機能するようにコードを更新する必要がありました。ちなみに、MarkViewは素晴らしいマークダウンファイルを読み書きするためのツールであり、コンテンツアウトライン、並べ替え可能なテーブル、コードブロック構文の強調表示、行番号などの機能を提供します。

私もこの投稿を作成しました。コメントは歓迎します。


2
正しいハックはopen(location, '_self').close();-からの戻り値の使用に注意してくださいopen()。これは引き続きChromeで機能します36.0.1985.125 m
ブロックアダムス

私の場合、でもう一度テストしましたがopen(location, '_self').close();、これで「不正」エラーが発生しました。このエラーは、 'window.close()(warning on this"Scripts may close only the windows that were opened by it."). It looked like open(location、' _self ')。close(); `が少し前に移動した場合とは異なりますが、私の場合は完了できません。コメントをありがとう@ brock-adams
swcool 14

私はtypescriptを持っています、そしてchrome.windows.removeそれを置くとき、それはシンボルクロムを見つけることができなかったと言います。どうすればこれを解決できますか?何らかの参照を追加する必要がありますか?
DevT 14

@devt chrome.windows.removeはChrome拡張APIであり、JavaScriptはChrome拡張プログラムによって認識される必要があります。background.js内で、必要なchrome拡張manifest.jsonで試すことができます。 "background":{"scripts":["background.js"]、...}、
swcool

MarkViewログイン機能を削除して、ユーザーが自由にアクセスできるようにしました。したがって、上記で述べた例は現在利用できません。
swcool 2016

21

今tampermonkeyであなたは使うことができます

// @grant        window.close

そして、単に電話するだけです

window.close();

私はこれが多くの場合に機能することを確認しましたが、たまに頑固なものでもまだ何もないよりはましです。投稿に追加します。
GµårÐïåñ

2
ちょうどメモ:Greasemonkey 3.10で私のために働いていません
mt025

17

私はBrock Adamsによって投稿された方法を使用しており、ユーザーが開始したものであれば、Firefoxでも機能します。

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

私はボタンを押してそれを呼び出しているので、ユーザーが開始しますが、Chrome 35-40、Internet Explorer 11、Safari 7-8、ALSO Firefox 29-35を使用しても問題なく機能します。Windows 8.1とMac OS X 10.6、10.9、10.10のバージョンが異なる場合は、それらを使用してテストしました。


自己終了ウィンドウコード(それ自体を閉じるページ上)

自分自身を閉じることができる、ユーザーが開いたウィンドウで使用される完全なコード:

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

次のテストページを試してください:(現在Chrome 40およびFirefox 35でテスト済み)

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


ウィンドウオープナーコード(上のページを開くページ)

これを機能させるには、セキュリティが課すクロスブラウザー互換性により、ユーザーが同じサイトドメイン内のボタンをクリックして、閉じるウィンドウが既に開かれている必要があります。

たとえば、上記のメソッドを使用してウィンドウを閉じるウィンドウは、次のコードを使用してページから開くことができます(上記のリンク先のサンプルページから提供されるコード)。

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

ユーザーが開始した例外を忘れました。良いキャッチ。ほとんどのユーザースクリプターは完全自動操作を望んでいると思います。彼らはすでに、ユーザーが開始する便利なクローズメカニズムを持っています-右上の小さなXです。(^_^)
ブロックアダムス

1
どういうわけか、これは私にはうまくいきません。Firefox 30でもChrome 37でもありません。ページを空白にするだけです(実際には奇妙な動作です)。私のコードは<button onclick="open(location,'_self').close()" >Close Window</button>です。私は明らかに間違っていることをしていますか?これもユーザー主導のようです。<button>またはを使用しても同じ結果が得られることに注意してください<input type="button">
LordOfThePigs 2014

上記のテストページを回答に追加しました。
ジェフクレイトン

@YumYumYum投稿への感謝、bitbucket.orgは最近bitbucket.ioへのリンクを変更しました-回答で修正済み
Jeff Clayton

それは私のために動作します(ウィンドウを閉じるためのページにボタンがあります)。うまくいかなかったのは:window.open('', '_self', ''); window.close(); しかし、それはうまくいった open(location, '_self').close();
krystonen

10

多くの人がまだJavaScriptを使用してChromeブラウザを閉じる方法を見つけようとしています。次の方法は、アプリランチャーとしてChromeを使用する場合にのみ機能します-たとえばキオスク!

私は以下をテストしました:

次の拡張機能を使用しています:キオスクを閉じる

私は使用手順に従っており、それは正常に動作するようです(テストを実行している間はキャッシュをクリアしてください)。私が使用するJavaScriptは(クリックイベントに添付されています):

window.location.href = '/closekiosk';

それが私が見つけた唯一の実用的な解決策であるので、それが誰かを助けることを願っています。

注:拡張機能がバックグラウンドで実行され、Chromeトレイアイコンが追加されているようです。次のオプションがチェックされています:「Chromeをバックグラウンドで実行する」(または同様のテキスト)。それがあなたのために働くまで、あなたはそれで遊ぶ必要があるかもしれません。チェックを外したところ、問題なく動作しました。


9

それが「明らかに虚偽」であると考えていても、あなたが「信念であると思われる」とあなたが言うことは実際には正しいです。window.closeのMozillaドキュメントは言う

このメソッドは、window.openメソッドを使用してスクリプトによって開かれたウィンドウに対してのみ呼び出すことができます。スクリプトによってウィンドウが開かれなかった場合、JavaScriptコンソールに次のエラーが表示されます。スクリプトが、スクリプトによって開かれていないウィンドウを閉じない可能性があります

「まだやるはずだ」とおっしゃっていますが、それを裏付けるリファレンスは見当たらないと思いますが、何か覚えていませんか?


9

私のためにうまく機能する新しい方法を見つけました

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

1
これは2017年ですが、「スクリプトによって開かれていないウィンドウがスクリプトによって閉じられない可能性があります」というエラーが表示されます。
Rotimi

IE 11の確認ボタンの素敵なハック
Gopal00005

ChromeとFirefoxで動作します
Vineeth Pradhan

1
この穴は埋められたようです。現時点ではわかりませんが、最新の開発ビルド84.xを使用しています。空白のページは読み込まれますが、クローズは発生しません。
スコットクリステンセン

4

以下のコードは私のために働きました-

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

Chrome 43.0.2357.81でテスト済み


Chromeバージョンを追加できますか?
ステファン

私のChromeバージョンは43.0.2357.81です。
DfrDkn 2015年

7
私にとっては、現在のウィンドウを/ locationのウィンドウに置き換えるだけです。
alianos-

@ alianos-私にとっても。
RicardoGonzales

1
最新のChromeでは動作しない-バージョン61.0.3163.100(公式ビルド)(64ビット)
Subhajit

1

これは古いかもしれませんが、答えましょう。

top.close()を使用してタブを閉じます。window.close()または他のopen ... closeが機能しませんでした。


11
これ"Scripts may not close windows that were not opened by script."は、他の回答で言及されている問題にも悩まされています。
kad81 2014

1
あなたの答えを解決してください。あなたの答えだけで問題を議論しないでください。
Bimal Das 2017

0

私の場合、ページを閉じる必要がありましたが、リンクによって開かれた可能性があるためwindow.close、失敗しました。

私が選択した解決策は、を発行しwindow.close、その後にwindow.setTimeout別のページにリダイレクトするを発行することです。

こうwindow.closeすると、成功した場合、そのページでの実行は停止しますが、失敗した場合は、1秒後に別のページにリダイレクトされます。

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

0

ブロックからのこの答えはそれが私のために働くようにします。同じJavaScriptで開かれていないウィンドウをJavaScriptが閉じてはいけません。

親のJavaScriptから子ウィンドウを閉じる場合にのみ、子ウィンドウを閉じることができます。だから私の両親では、このようなことをすることができます。

var myChildWindow;

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

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

-1

以下のコードを使用してみることもできます。これは、親ウィンドウをリダイレクトするのにも役立ちます。

親:

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

現れる:

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

上で述べたように、window.open()を使用して新しいウィンドウを開く場合にのみ、新しいウィンドウはコードを使用して閉じることができます。これは私にとっては完璧に機能します:)注:hrefを使用してページを新しいタブで開くことは絶対にしないでください。Window.close()は "href"では機能しません。代わりにwindow.open()を使用してください。


1
現在のウィンドウを置き換えるだけです。もういや。
RicardoGonzales

-3

この問題について私の「解決策」を共有したいと思いました。私たちのほとんどは、ユーザーが他のWebサイトにアクセスした後、他のWebサイトにアクセスする前に、標準のブラウザーセッションでブラウザーウィンドウを閉じようとしているようです。

ただし、私の状況では、デバイスが実行するのは本質的に唯一のデバイスになるWebアプリを構築しているということです。起動するとChromeが起動し、アプリに移動します。インターネットに接続されておらず、通信するサーバーはすべてローカルのDockerコンテナー上にあります。ユーザーは、端末にアクセスしてシステム更新を実行できるように、アプリを閉じる方法(別名Chromeを閉じる)が必要です。

つまり、起動してChromeをキオスクモードで正しいアドレスで起動します。これはたまたま、仕様の2番目のオプションを簡単に満たします。

ブラウジングコンテキストは、(ユーザーのアクションではなく)スクリプトによって作成された補助的なブラウジングコンテキストである場合またはセッション履歴に1つのドキュメントのみが含まれるトップレベルのブラウジングコンテキストである場合、スクリプトで閉じることができます。

したがってwindow.close()、キオスクアプリから呼び出すだけでうまくいきます


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.