window.close dan self.close jangan tutup jendela di Chrome

174

Masalahnya adalah ketika saya memohon window.close()atau self.close()tidak menutup jendela. Sekarang tampaknya ada kepercayaan bahwa di Chrome Anda tidak dapat menutup dengan skrip jendela apa pun yang bukan skrip dibuat. Itu benar-benar salah tetapi terlepas dari itu seharusnya masih melakukannya, bahkan jika itu perlu muncul peringatan untuk mengonfirmasi. Ini tidak terjadi.

Jadi apakah ada yang punya metode nyata, fungsional dan terbukti menutup jendela menggunakan sesuatu seperti javascript:window.close()atau javascript:self.close()yang benar-benar melakukan apa yang diharapkan dan sesuatu yang terjadi dengan baik di setiap browser yang BUKAN berbasis Chrome? Setiap saran akan sangat dihargai dan saya mencari solusi spesifik Javascript, bukan JQuery atau implementasi pihak ketiga.

Pembaruan: Sementara banyak dari apa yang telah disarankan memiliki keterbatasan serius dan masalah kegunaan, saran terbaru (khusus untuk TamperMonkey) menggunakan // @grant window.closedi header skrip akan sering melakukan trik bahkan pada tab yang biasanya tidak dapat menangani metode penutupan. Meskipun tidak sepenuhnya ideal dan tidak digeneralisasikan untuk setiap kasus, ini adalah solusi yang baik untuk kasus saya.

GμårÐïåñ
sumber
window.close()bekerja untuk saya di chrome.
mash
3
@ GμårÐïåñ: Umm, bukan itu. Itu tidak ada hubungannya dengan bahasa. Ini adalah fungsi yang diterapkan oleh browser. Jika Anda dapat menulis contoh minimal yang menunjukkan bagaimana window.closetidak berfungsi sebagaimana mestinya, saya pikir itu mungkin lebih bermanfaat daripada mengatakan, "itu tidak berhasil".
Blender
3
Saya memberi Anda DUA contoh. Menjabarkannya untuk Anda,<a href="javascript:window.close">CLOSE</a>
GμårÐïåñ
3
wali yang tidak tepat javascript. Coba window.close () dan berhasil. window.close hanyalah nama variabel dan tidak akan memanggil fungsi (setidaknya tidak ketika saya mengujinya di chrome 37). Ketika saya mengubah contoh Anda ke window.close () itu bekerja di chrome 37.
George
3
GμårÐïåñ Apa yang dikatakan @George BUKAN diperdebatkan (kecuali saya benar-benar salah mengerti arti kata itu) Dia benar dalam menyatakan bahwa Anda memiliki kesalahan sintaksis dalam javascript dalam contoh Anda, dan jika Anda memiliki kesalahan yang sama dalam kode aplikasi Anda, maka ini kemungkinan besar menjadi penyebab masalah Anda. JIKA, bagaimanapun, ini hanya kesalahan ketik dalam contoh Anda, maka Anda harus memperbaiki kesalahan ketik itu untuk mendapatkan jawaban yang lebih baik.
Superole

Jawaban:

187

Javascript biasa tidak bisa menutup windows mau tak mau. Ini adalah fitur keamanan, diperkenalkan beberapa waktu lalu, untuk menghentikan berbagai eksploitasi dan gangguan yang berbahaya.

Dari spesifikasi kerja terbaru untukwindow.close() :

The close()Metode pada Window objek harus, jika semua kondisi berikut terpenuhi, dekat konteks penjelajahan A :

  • Konteks penelusuran yang sesuai A adalah script-closable .
  • Konteks browsing script menjabat akrab dengan konteks penjelajahan A .
  • Konteks yang sedang berada naskah menjabat diperbolehkan untuk menavigasi konteks penjelajahan A .

Konteks penelusuran dapat ditutup script jika konteks penelusuran tambahan yang dibuat oleh skrip (sebagai lawan dari tindakan pengguna), atau jika konteks penelusuran yang riwayat sesi hanya berisi satu dokumen.

Ini berarti, dengan satu pengecualian kecil, javascript tidak boleh diizinkan untuk menutup jendela yang tidak dibuka oleh javascript yang sama.

Chrome mengizinkan pengecualian itu - yang tidak berlaku untuk skrip pengguna - namun Firefox tidak. Standar implementasi Firefox menyatakan :

Metode ini hanya diperbolehkan dipanggil untuk windows yang dibuka oleh skrip menggunakan window.openmetode ini.


Jika Anda mencoba menggunakan window.closedari skrip Greasemonkey / Tampermonkey / users Anda akan mendapatkan:
Firefox: Pesan kesalahan, " Scripts may not close windows that were not opened by script."
Chrome: gagal dalam diam-diam.



Solusi jangka panjang:

Cara terbaik untuk mengatasinya adalah dengan membuat ekstensi Chrome dan / atau Firefox sebagai tambahan. Ini dapat dipercaya menutup jendela saat ini.

Namun, karena risiko keamanan, yang ditimbulkan oleh window.close, jauh lebih sedikit untuk skrip Greasemonkey / Tampermonkey; Greasemonkey dan Tampermonkey secara wajar dapat menyediakan fungsionalitas ini dalam API mereka (pada dasarnya mengemas pekerjaan ekstensi untuk Anda).
Pertimbangkan untuk membuat permintaan fitur.



Solusi peretasan:

Chrome saat ini rentan terhadap eksploitasi "pengalihan sendiri". Jadi kode seperti ini digunakan untuk bekerja secara umum:

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

Ini adalah perilaku buggy, IMO, dan sekarang (sekitar April 2015) sebagian besar diblokir. Itu masih akan bekerja dari kode yang disuntikkan hanya jika tab baru dibuka dan tidak memiliki halaman dalam riwayat penjelajahan. Jadi itu hanya berguna dalam situasi yang sangat kecil.

Namun, variasi masih berfungsi di Chrome (v43 & v44) plus Tampermonkey (v3.11 atau lebih baru) . Gunakan yang eksplisit @grantdan polos window.close(). MISALNYA:

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

setTimeout (window.close, 5000);

Terima kasih kepada zanetu untuk pembaruannya. Perhatikan bahwa ini tidak akan berfungsi jika hanya ada satu tab yang terbuka. Itu hanya menutup tab tambahan.


Firefox aman terhadap eksploitasi itu. Jadi, satu-satunya cara javascript adalah melumpuhkan pengaturan keamanan, satu per satu browser.

Anda dapat membuka about:configdan mengatur
allow_scripts_to_close_windowske true.

Jika skrip Anda untuk penggunaan pribadi, silakan dan lakukan itu. Jika Anda meminta orang lain untuk mengaktifkan pengaturan itu, mereka akan menjadi pintar, dan dibenarkan, untuk menolak dengan prasangka.

Saat ini tidak ada pengaturan yang setara untuk Chrome.

Brock Adams
sumber
3
Hai teman saya, senang akhirnya mendengar dari Anda. Hanya sebuah catatan, pada Fx Anda dapat melewati batasan itu dengan membalik dom.allow_scripts_to_close_windows;falseke truetapi saya rasa tidak ada apa-apa di Chrome tanpa meretas sumber / membangun kembali yang merupakan cara saya mengatasinya untuk saat ini. Saya tahu dan telah berbicara dengan pengembang TM dan dalam alpha / beta baru-baru ini kami menempatkannya sebagai opsi kompatibilitas (pengaturan skrip) untuk berjalan dalam gaya man-in-the-middle, berfungsi. Saya kira pendek dari peretasan kami tidak memiliki solusi bersih, kasihan.
GμårÐïåñ
3
Jika ada yang mengalami masalah dengan window.close atau perbedaan perilaku tertentu di antara browser, baca jawaban ini dengan sangat hati-hati - itu memang memiliki semua informasi yang benar.
Bron Davies
Apakah ada cara untuk memeriksa apakah jendela dibuka dengan skrip atau tidak? (Saya perlu menunjukkan / menyembunyikan tombol kembali, saya tidak ingin menggunakan
retasan
Sejak Chrome 36.0.1985.125 RABU, 16 JULI 2014, Pemecahan masalah mungkin tidak berfungsi, detail dalam jawaban saya.
swcool
2
window.close()akan bekerja di Tampermonkey jika Anda menetapkan @grantnilai selain none. Lihat utas ini .
zanetu
32

Chrome Memperbaiki masalah keamanan pada versi 36.0.1985.125

Chrome 36.0.1985.125 RABU, 16 JULI 2014 Catatan rilis

Dari pengamatan saya, pembaruan ini memperbaiki masalah penggunaan window.close()untuk menutup jendela sembulan. Anda akan melihat ini di konsol ketika gagal, "Script dapat menutup hanya jendela yang dibuka olehnya." Itu berarti The hacky workarounds (jawaban Brock Adams) mungkin tidak berfungsi dalam rilis terbaru.

Jadi, di build Chrome yang dirilis sebelumnya, blok kode di bawah ini mungkin berfungsi tetapi tidak dengan pembaruan ini.

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

Untuk pembaruan ini, Anda harus memperbarui kode Anda sesuai untuk menutup jendela sembulan. Salah satu solusinya adalah dengan mengambil id jendela popup dan menggunakannya

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

metode untuk menghapusnya. API jendela ekstensi Chrome dapat ditemukan di chrome.windows .

Sebenarnya ekstensi chrome saya MarkView menghadapi masalah ini dan saya harus memperbarui kode saya agar berfungsi untuk Pembaruan Chrome ini. Omong-omong, MarkView adalah alat untuk membaca dan menulis File Markdown yang Luar Biasa, MarkView menyediakan fitur termasuk Content Outline, Sortable Tables, dan highlight sintaks blok kode dengan nomor baris.

Saya juga membuat posting ini , ada komentar yang diterima.

swcool
sumber
2
Retasan yang benar adalah open(location, '_self').close();- perhatikan penggunaan nilai balik dari open(). Ini masih berfungsi di Chrome36.0.1985.125 m
Brock Adams
Dalam kasus saya, saya hanya menguji lagi dengan open(location, '_self').close();, saya mendapat kesalahan "Tidak Sah" dalam hal ini. Kesalahan ini berbeda dengan 'window.close () (warning on this"Scripts may close only the windows that were opened by it."). It looked like open (location,' _self '). Close (); `bergerak sedikit ke depan, tetapi tidak dapat menyelesaikan dalam kasus saya. Terima kasih @ brock-adams atas komentarnya.
swcool
Saya memiliki naskah dan ketika saya chrome.windows.removemengatakannya tidak dapat menemukan simbol chrome. bagaimana saya bisa menyelesaikan ini? apakah saya perlu menambahkan semacam referensi?
DevT
@devt chrome.windows.remove adalah API ekstensi Chrome, javascript Anda harus dikenali oleh program ekstensi chrome Anda. Anda dapat mencobanya di dalam background.js, di manifes ekstensi chrome Anda, Anda harus memiliki: "latar belakang": {"skrip": ["background.js"], ...},
swcool
Saya telah menghapus fungsi login MarkView agar pengguna dapat mengakses dengan bebas. Jadi contoh yang saya sebutkan di atas tidak tersedia sekarang.
swcool
21

Di tampermonkey sekarang Anda bisa menggunakan

// @grant        window.close

Dan kemudian cukup menelepon

window.close();
botak
sumber
Saya telah mengkonfirmasi bahwa ini berfungsi dalam banyak hal tetapi masih sesekali keras kepala tetapi lebih baik daripada tidak sama sekali, terima kasih. Saya akan menambahkannya ke posting.
GμårÐïåñ
2
Sama seperti catatan: Tidak bekerja untuk saya di Greasemonkey 3.10
mt025
17

Saya menggunakan metode yang diposting oleh Brock Adams dan bahkan berfungsi di Firefox, jika itu diinisiasi pengguna.

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

Saya memanggilnya dari tombol tekan sehingga pengguna diinisiasi , dan masih berfungsi baik menggunakan Chrome 35-40, Internet Explorer 11, Safari 7-8 dan JUGA Firefox 29-35. Saya diuji menggunakan versi 8.1 Windows dan Mac OS X 10.6, 10.9 & 10.10 jika itu berbeda.


Kode Jendela Penutupan Sendiri (pada halaman yang menutup sendiri)

Kode lengkap untuk digunakan pada jendela yang dibuka pengguna yang dapat menutup sendiri:

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

Coba halaman pengujian ini: (Sekarang diuji di Chrome 40 dan Firefox 35)

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


Kode Pembuka Jendela (pada halaman yang membuka halaman di atas)

Untuk membuat ini berfungsi, kompatibilitas lintas browser yang diberlakukan keamanan mensyaratkan bahwa jendela yang akan ditutup harus sudah dibuka oleh pengguna mengklik tombol dalam domain situs yang sama.

Misalnya, jendela yang menggunakan metode di atas untuk menutup sendiri, dapat dibuka dari halaman menggunakan kode ini (kode disediakan dari halaman contoh saya yang ditautkan di atas):

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
sumber
Lupa tentang pengguna yang memulai pengecualian; tangkapan yang bagus. Saya pikir sebagian besar pengguna skrip ingin operasi sepenuhnya otomatis. Mereka sudah memiliki mekanisme penutupan yang praktis dan dimulai oleh pengguna - X kecil di kanan atas. (^_^)
Brock Adams
1
Entah bagaimana, ini tidak berhasil untuk saya. Baik di firefox 30 maupun di Chrome 37. Yang dilakukannya hanyalah membuat halaman menjadi kosong (perilaku yang sangat aneh). Kode saya adalah <button onclick="open(location,'_self').close()" >Close Window</button>. Apakah saya melakukan sesuatu yang jelas salah? Bagiku ini juga diprakarsai oleh pengguna. Perhatikan bahwa saya mendapatkan hasil yang sama jika saya menggunakan a <button>atau a <input type="button">.
LordOfThePigs
Menambahkan halaman pengujian di atas dalam jawaban untuk Anda.
Jeff Clayton
@YumYumYum terima kasih atas kirimannya, bitbucket.org mengubah tautan menjadi bitbucket.io baru-baru ini - memperbaiki jawabannya sekarang
Jeff Clayton
Ini berfungsi untuk saya (memiliki tombol pada halaman untuk menutup jendela). Apa yang tidak berhasil adalah: window.open('', '_self', ''); window.close(); tetapi berhasil dengan open(location, '_self').close();
krystonen
10

Banyak orang masih berusaha menemukan cara untuk menutup browser Chrome menggunakan javascript. Metode berikut hanya berfungsi ketika Anda menggunakan Chrome sebagai peluncur aplikasi - misalnya kios!

Saya telah menguji yang berikut ini:

Saya menggunakan ekstensi berikut: Tutup Kios

Saya mengikuti petunjuk penggunaan dan tampaknya berfungsi dengan baik (pastikan Anda menghapus cache saat melakukan tes). Javascript yang saya gunakan adalah (terlampir untuk mengklik acara):

window.location.href = '/closekiosk';

Saya harap itu membantu seseorang, karena itu satu-satunya solusi yang saya temukan.

Catatan: Tampaknya ekstensi berjalan di latar belakang dan menambahkan ikon baki Chrome. Opsi berikut dicentang: "Biarkan Chrome berjalan di latar belakang" (atau teks serupa). Anda mungkin perlu bermain dengannya, sampai berhasil. Saya tidak mencentangnya dan sekarang berfungsi dengan baik!

Menteri
sumber
9

Meskipun berpikir itu "benar-benar salah", apa yang Anda katakan "tampaknya menjadi kepercayaan" sebenarnya benar. Dokumentasi Mozilla untuk window.close mengatakan

Metode ini hanya diperbolehkan dipanggil untuk windows yang dibuka oleh skrip menggunakan metode window.open. Jika jendela tidak dibuka oleh skrip, kesalahan berikut muncul di Konsol JavaScript: Skrip mungkin tidak menutup jendela yang tidak dibuka oleh skrip

Anda mengatakan bahwa itu "seharusnya tetap melakukannya" tetapi saya tidak berpikir Anda akan menemukan referensi yang mendukung itu, mungkin Anda salah ingat sesuatu?

Gareth
sumber
9

Saya menemukan cara baru yang bekerja untuk saya dengan sempurna

var win = window.open("about:blank", "_self");
win.close();
Gerardo Abdo
sumber
1
ini tahun 2017 dan saya masih mendapatkan kesalahan "Script mungkin tidak menutup windows yang tidak dibuka oleh script."
Rotimi
Retasan
Bekerja di Chrome dan Firefox
Vineeth Pradhan
1
Lubang ini sepertinya sudah terisi. Saya tidak tahu kapan tetapi saya menggunakan dev terbaru build 84.x. Halaman kosong dimuat tetapi tutupnya tidak menyala.
Scott Christensen
4

Kode di bawah ini berfungsi untuk saya -

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

Diuji pada Chrome 43.0.2357.81

DfrDkn
sumber
Bisakah Anda menambahkan versi Chrome Anda?
Stephan
Versi chrome saya adalah 43.0.2357.81.
DfrDkn
7
Bagi saya yang baru saja mengganti jendela saat ini, dengan jendela di / lokasi.
alianos-
@ Alianos- untuk saya juga.
RicardoGonzales
1
Tidak berfungsi di chrome terbaru - Versi 61.0.3163.100 (Bangun Resmi) (64-bit)
Subhajit
1

Ini mungkin sudah tua, tapi mari kita jawab.

Saya menggunakan top.close () untuk menutup tab. window.close () atau buka lainnya ... tutup tidak berfungsi untuk saya.

Soley
sumber
11
Ini juga menderita "Scripts may not close windows that were not opened by script."masalah yang disebutkan dalam jawaban lain.
kad81
1
tolong berikan solusi atas jawaban Anda. tolong jangan hanya membahas masalah pada jawaban Anda.
Bimal Das
0

Dalam kasus saya, halaman perlu ditutup, tetapi mungkin telah dibuka oleh tautan dan karenanya window.closeakan gagal.

Solusi yang saya pilih adalah dengan menerbitkan window.close, diikuti oleh window.setTimeoutyang mengalihkan ke halaman lain.

Dengan begitu, jika window.closeberhasil, eksekusi pada halaman itu berhenti, tetapi jika gagal, dalam sedetik, itu akan dialihkan ke halaman lain.

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

Jawaban dari Brock membuatnya bekerja untuk saya. javascript tidak boleh diizinkan untuk menutup jendela yang tidak dibuka oleh javascript yang sama.

Saya hanya bisa menutup jendela anak jika saya akan menutupnya dari javascript induk. jadi pada orang tua saya, saya bisa melakukan sesuatu seperti ini.

var myChildWindow;

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

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

Anda juga dapat mencoba menggunakan kode saya di bawah ini. Ini juga akan membantu Anda untuk mengarahkan ulang jendela induk Anda:

Induk:

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

Muncul:

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

Hanya jika Anda membuka jendela baru menggunakan window.open () maka jendela baru dapat ditutup menggunakan kode seperti yang saya sebutkan di atas. Ini berfungsi dengan baik untuk saya :) Catatan: Jangan pernah menggunakan href untuk membuka halaman di tab baru. Window.close () tidak berfungsi dengan "href". Gunakan window.open () sebagai gantinya.

DfrDkn
sumber
1
Itu hanya mengganti jendela curren. Tidak lagi.
RicardoGonzales
-3

Saya ingin membagikan "solusi" saya dengan masalah ini. Sepertinya sebagian besar dari kita mencoba untuk menutup jendela browser dalam sesi browser standar, di mana pengguna mengunjungi beberapa situs web, setelah mereka mengunjungi situs web lain, dan sebelum mereka mengunjungi situs web lain.

Namun, situasi saya adalah saya membuat aplikasi web untuk perangkat yang pada dasarnya akan menjadi satu-satunya hal yang dilakukan perangkat. Anda mem-boot-nya, meluncurkan Chrome dan menavigasi ke aplikasi kami. Bahkan tidak terhubung ke internet, server mana pun yang diajak bicara berada di wadah Docker lokal kami. Pengguna membutuhkan cara untuk menutup aplikasi (alias tutup Chrome) sehingga mereka dapat mengakses terminal untuk melakukan pembaruan sistem.

Jadi boot, luncurkan Chrome dalam mode kios, di alamat yang benar. Ini terjadi untuk dengan mudah memenuhi opsi kedua dalam spesifikasi:

Konteks penelusuran dapat ditutup skrip jika konteks penelusuran tambahan yang dibuat oleh skrip (tidak seperti tindakan pengguna), atau jika konteks penelusuran tingkat atas yang riwayat sesi hanya berisi satu dokumen.

Jadi cukup menelepon window.close()dari aplikasi kios saya hanya berfungsi !

Jonathan Tuzman
sumber
-5

Coba sesuatu seperti ini onclick = "return self.close ()"

Ragven
sumber