Cara bermain Chat Antar Tab
- Baca instruksi level. Arena menampilkan tab dan iframe berdampingan, lengkap dengan origin masing-masing. Tab bertanda kodemu adalah tempat kodemu dijalankan.
- Tulis kodenya di editor.
tampil(...)menulis gelembung chat ke layar tab yang menjalankan kode itu. - Gelembung oranye di kanan ditulis langsung oleh kode tab itu. Gelembung di kiri adalah reaksi atas pesan yang masuk, dengan nama pengirimnya. Gelembung abu putus-putus berarti pesannya sampai tapi tidak ada yang bereaksi, dan gelembung merah berarti browser membuangnya.
- Di bawahnya, Jalan cerita memutar kejadian level satu per satu sekali setiap kodemu berubah, dengan garis kiriman dari pengirim ke penerima.
- Tekan Cek jawaban atau Ctrl + Enter. Yang dicek adalah pesan yang terkirim, sampai, atau dibuang, isi layar tiap tab, dan kanal yang masih terbuka di akhir, dibandingkan dengan jawaban acuan.
- Kalau buntu, buka Petunjuk. Petunjuk pertama mengarahkan, petunjuk terakhir hampir menjawab.
- Level yang sudah selesai tetap tercentang saat kamu kembali dengan browser yang sama.
Yang kamu pelajari
- Level 1
BroadcastChannel dan onmessage
new BroadcastChannel(nama)membuka kanal. Semua tab di origin yang sama yang membuka kanal bernama sama menerima pesannya lewatonmessage, dengan isi dievent.data. - Level 2
postMessage ke banyak tab
kanal.postMessage(data)sekali saja sampai ke semua kanal lain bernama sama, berapa pun jumlah tabnya. - Level 3
addEventListener("message")
onmessagehanya menyimpan satu fungsi.addEventListenermenambah pendengar tanpa membuang yang sudah ada. - Level 4
Pengirim tidak menerima pesannya sendiri
Kanal mengantar ke semua objek bernama sama kecuali objek yang memanggil
postMessage, jadi tab pengirim harus menampilkan pesannya sendiri. - Level 5
close()
Memutus kanal. Pesan yang dikirim sesudahnya, termasuk yang sudah mengantre, tidak diantar lagi ke kanal itu.
- Level 6
Structured clone
Data dikirim sebagai salinan. Objek, array,
Date, danMapbisa disalin, fungsi tidak dan memicuDataCloneError. - Level 7
Disalin saat dikirim
Perubahan objek setelah
postMessagedipanggil tidak ikut terkirim, karena penerima memegang salinannya sendiri. - Level 8
window.postMessage dan targetOrigin
iframe.contentWindow.postMessage(data, targetOrigin)mengirim ke jendela lain, termasuk beda origin. Kalau origin tujuannya tidak cocok, browser membuang pesannya tanpa error. - Level 9
Bahaya targetOrigin *
"*"mengirim ke halaman apa pun yang sedang ada di jendela itu, termasuk iframe yang sudah dialihkan ke situs lain. - Level 10
Validasi event.origin
Penerima harus membandingkan
event.origindengan origin yang dipercaya, karena siapa pun bisa mengirim pesan ke jendelamu. - Level 11
Membalas lewat event.source
event.sourceadalah jendela pengirim. Balas denganevent.source.postMessage(data, event.origin). - Level 12
Event storage
Cara lama sinkron antar tab: mengubah
localStoragememicu eventstoragedi tab lain ber-origin sama, tidak di tab yang mengubahnya.
targetOrigin melindungi pengirim, event.origin melindungi penerima
Ada dua pemeriksaan origin di window.postMessage, dan keduanya menjaga sisi yang berbeda. targetOrigin ditulis pengirim: "pesan ini hanya untuk halaman dari https://bayar.id". Browser memeriksa origin halaman yang sedang ada di jendela tujuan saat pesan diantar, dan membuangnya kalau tidak cocok. Ini menjaga data rahasia tidak bocor ke iframe yang sudah dialihkan, seperti di level 9.
Sebaliknya, siapa pun boleh mengirim pesan ke jendelamu dengan targetOrigin "*". Penerima tidak bisa mencegah pesannya datang, jadi penerima harus memeriksa event.origin sebelum mempercayai isinya, seperti di level 10. Isi pesan bisa dipalsukan, tapi event.origin diisi browser. BroadcastChannel tidak butuh keduanya karena hanya menghubungkan tab ber-origin sama.
Tanya jawab
Apakah harus daftar akun untuk bermain?
Tidak. Semua level bisa dimainkan tanpa akun. Kemajuanmu disimpan di browser yang kamu pakai, jadi akan hilang kalau data browser dihapus.
Apa beda BroadcastChannel dan window.postMessage?
BroadcastChannel menghubungkan semua tab, jendela, dan iframe ber-origin sama yang membuka kanal bernama sama, tanpa perlu saling memegang referensi. window.postMessage mengirim ke satu jendela tertentu yang kamu pegang, mis. iframe.contentWindow, parent, atau hasil window.open, dan boleh beda origin.
Bisakah BroadcastChannel dipakai antar domain berbeda?
Tidak. Kanal hanya menghubungkan konteks dengan origin yang sama persis, jadi warung.id dan bayar.id tidak bisa saling dengar walau nama kanalnya sama. Untuk beda origin, pakai window.postMessage dengan targetOrigin dan cek event.origin.
Kenapa pesanku tidak sampai tanpa error apa pun?
Ada tiga sebab yang sering terjadi: nama kanal berbeda (huruf besar kecil juga dihitung), kanal penerima sudah close(), atau targetOrigin di window.postMessage tidak cocok dengan origin halaman tujuan. Ketiganya diam saja, tanpa error di console. Di arena, pesan seperti itu ditandai abu atau merah.
Kapan masih perlu event storage?
Hampir tidak pernah untuk kode baru, karena BroadcastChannel sudah didukung semua browser modern. Event storage tetap berguna kalau datanya memang harus disimpan, mis. status keluar akun yang juga harus terbaca saat tab baru dibuka, karena localStorage bertahan sedangkan pesan kanal hilang begitu diantar.
Apakah kodeku benar-benar membuka tab baru?
Tidak. Tab, iframe, BroadcastChannel, postMessage, dan localStorage di game ini tiruan yang berjalan di Web Worker sandbox. Pesan diantar berurutan setelah kode pengirimnya selesai, sama seperti browser, dan hasilnya selalu sama setiap dijalankan. Belum ditiru: MessageChannel dan port, window.open, dan Worker sebagai penerima.