it-swarm-id.com

Mengapa elemen skrip penutup otomatis tidak berfungsi?

Apa alasan browser tidak mengenali dengan benar:

<script src="foobar.js" /> <!-- self-closing script element -->

Hanya ini yang dikenali:

<script src="foobar.js"></script>

Apakah ini mematahkan konsep dukungan XHTML?

Catatan: Pernyataan ini setidaknya benar untuk semua IE (6-8 beta 2).

1247
dimarzionist

Spesifikasi XHTML 1 mengatakan:

С.3. Minimalisasi Elemen dan Konten Elemen Kosong

Diberikan contoh kosong elemen yang model kontennya bukan EMPTY (misalnya, judul atau paragraf kosong) tidak menggunakan formulir yang diperkecil (mis. Gunakan <p> </p> dan bukan <p />).

XHTML DTD menetapkan elemen skrip sebagai:

<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>
456
squadette

Untuk menambah apa yang dikatakan Brad dan skuadet, sintaks XML yang menutup sendiri <script /> sebenarnya adalah XML yang benar, tetapi agar bisa bekerja dalam praktiknya, web Anda server juga perlu mengirim dokumen Anda sebagai XML yang dibentuk dengan benar dengan mimetype XML seperti application/xhtml+xml di header Jenis Konten HTTP (dan bukan sebagai text/html).

Namun, mengirimkan mimetype XML akan menyebabkan halaman Anda tidak diuraikan oleh IE7, yang hanya menyukai text/html.

Dari w :

Singkatnya, 'application/xhtml + xml' HARUS digunakan untuk dokumen Keluarga XHTML, dan penggunaan 'teks/html' HARUS dibatasi untuk dokumen XHTML 1.0 yang kompatibel dengan HTML. 'application/xml' dan 'text/xml' MUNGKIN juga dapat digunakan, tetapi bila perlu, 'application/xhtml + xml' HARUS digunakan daripada jenis media XML yang umum.

Saya bingung mengenai hal ini beberapa bulan yang lalu, dan satu-satunya solusi yang dapat diterapkan (kompatibel dengan FF3 + dan IE7) adalah dengan menggunakan sintaks <script></script> lama dengan text/html (sintaks HTML + mimetype HTML).

Jika server Anda mengirim tipe text/html dalam header HTTPnya, bahkan dengan dokumen XHTML yang dibentuk dengan benar, FF3 + akan menggunakan mode rendering HTML yang berarti bahwa <script /> tidak akan berfungsi (ini adalah perubahan, Firefox sebelumnya kurang ketat).

Ini akan terjadi terlepas dari setiap mengutak-atik elemen meta http-equiv, prolog XML atau DOCTYPE di dalam dokumen Anda - Cabang Firefox setelah mendapat header text/html, yang menentukan apakah parser HTML atau XML terlihat di dalam dokumen, dan parser HTML tidak mengerti <script />.

225
joelhardi

Jika ada yang penasaran, alasan utamanya adalah bahwa HTML pada awalnya adalah dialek SGML, yang merupakan kakak lelaki tua XML yang aneh. Di tanah SGML, elemen dapat ditentukan dalam DTD sebagai penutupan sendiri (mis. BR, HR, INPUT), secara implisit dekat (mis. P, LI, TD), atau secara eksplisit dapat ditutup (mis. TABEL, DIV, SCRIPT). XML tentu saja tidak memiliki konsep ini.

Pengurai tag-tag yang digunakan oleh peramban modern berkembang dari peninggalan ini, meskipun model penguraian mereka bukan lagi SGML murni. Dan tentu saja XHTML Anda yang dibuat dengan hati-hati diperlakukan sebagai sup tag-terinspirasi SGML yang ditulis dengan buruk kecuali Anda mengirimnya dengan tipe mime XML. Ini juga sebabnya ...

<p><div>hello</div></p>

... ditafsirkan oleh browser sebagai:

<p></p><div>hello</div><p></p>

... yang merupakan resep untuk bug tak dikenal yang indah yang dapat membuat Anda cocok saat Anda mencoba kode melawan DOM.

150
greim

Yang lain telah menjawab "bagaimana" dan mengutip spec. Berikut adalah kisah nyata "mengapa tidak ada <script/>", setelah berjam-jam menggali laporan bug dan milis.


HTML 4

HTML 4 didasarkan pada SGML .

SGML memiliki beberapa shorttags , seperti <BR//, <B>text</>, <B/text/, atau <OL<LI>item</LI</OL>. XML mengambil bentuk pertama, mendefinisikan ulang akhiran sebagai ">" (SGML fleksibel), sehingga menjadi <BR/>.

Namun, HTML tidak didefinisikan ulang, jadi <SCRIPT/> seharusnya berarti<SCRIPT>>.
(Ya, '>' harus menjadi bagian dari konten, dan tag masih tidak ditutup.)

Jelas, ini tidak kompatibel dengan XHTML dan akan memecah banyak situs (pada saat browser sudah cukup matang ntuk pedulitentang ini ), jadi tidak ada yang menerapkan shorttags dan spesifikasinya menyarankan mereka .

Secara efektif, semua tag tanpa-diri 'berfungsi' adalah tag dengan tag akhir opsional pada parser yang secara teknis tidak sesuai dan pada kenyataannya tidak valid. Itu adalah W3C yang muncul dengan hack ini untuk membantu transisi ke XHTML dengan membuatnya HTML-compatible .

Dan tag akhir <script> adalah bukan opsional .

Tag "Tidak berakhir" adalah retasan dalam HTML 4 dan tidak berarti.


HTML 5

HTML5 memiliki lima jenis tag dan hanya tag 'void' dan 'asing' diizinkan untuk ditutup sendiri .

Karena <script> tidak batal (itu mungkin memiliki konten) dan tidak asing (seperti MathML atau SVG), <script> tidak dapat ditutup sendiri, terlepas dari bagaimana Anda menggunakannya.

Tapi kenapa? Tidak bisakah mereka menganggapnya sebagai benda asing, membuat kasus khusus, atau sesuatu?

HTML 5 bertujuan untuk menjadi kompatibel ke belakang dengan implementasi dari HTML 4 dan XHTML 1. Tidak didasarkan pada SGML atau XML; sintaksinya terutama berkaitan dengan mendokumentasikan dan menyatukan implementasi. (Inilah sebabnya <br/><hr/> dll. HTML 5 yang valid meskipun HTML4 tidak valid.)

Self-closing <script> adalah salah satu tag di mana implementasi yang digunakan berbeda. Ini dulu berfungsi di Chrome, Safari , dan Opera ; setahu saya itu tidak pernah bekerja di Internet Explorer atau Firefox.

Ini dibahas ketika HTML 5 sedang dirancang dan ditolak karena istirahatbrowserkompatibilitas . Laman web yang ditutup dengan tag skrip sendiri mungkin tidak ditampilkan dengan benar (jika ada) di peramban lama. Ada proposal lain , tetapi mereka juga tidak dapat menyelesaikan masalah kompatibilitas.

Setelah draft dirilis, WebKit memperbarui parser agar sesuai.

Menutup diri <script> tidak terjadi di HTML 5 karena kompatibilitas ke belakang ke HTML 4 dan XHTML 1.


XHTML 1/XHTML 5

Ketika really disajikan sebagai XHTML, <script/> benar-benar ditutup, seperti jawaban lain telah dinyatakan.

Kecuali bahwa spec mengatakan it seharusnya bekerja ketika disajikan sebagai HTML:

Dokumen XHTML ... dapat dilabeli dengan Jenis Media Internet "text/html" [RFC2854], karena mereka kompatibel dengan sebagian besar browser HTML.

Jadi apa yang terjadi?

Orang meminta Mozilla ke biarkan Firefox mengurai menyesuaikan dokumen sebagai XHTML terlepas dari header konten yang ditentukan (dikenal sebagai sniffing konten ). Ini akan memungkinkan skrip penutup sendiri, dan mengendus konten diperlukan tetap karena web hosters tidak cukup dewasa untuk melayani header yang benar; IE adalah pandai .

Jika perang browser pertama tidak diakhiri dengan IE 6, XHTML mungkin sudah ada dalam daftar juga. Tapi itu memang berakhir. Dan IE 6 memiliki masalah dengan XHTML. Sebenarnya IE tidak mendukung jenis MIME yang benar sama sekali , memaksa semua orang menggunakan text/html untuk XHTML karena IE memiliki pangsa pasar utama selama satu dekade penuh.

Dan juga mengendus konten bisasangat buruk dan orang-orang mengatakan harus dihentikan .

Akhirnya, ternyata W3C tidak berarti XHTML dapat sniffable : dokumennya adalah keduanya , HTML dan XHTML, dan aturan Content-Type. Bisa dikatakan mereka berdiri teguh pada "ikuti saja spec kami" dan mengabaikan apa yang praktis . Kesalahan yang lanjutan ke versi XHTML yang lebih baru.

Bagaimanapun, keputusan ini menyelesaikan masalah untuk Firefox. Itu 7 tahun sebelum Chrome lahir ; tidak ada browser signifikan lainnya. Jadi diputuskan.

Menentukan doctype saja tidak memicu penguraian XML karena spesifikasi berikut.

139
Sheepy

Internet Explorer 8 dan yang lebih lama tidak mendukung penguraian XHTML. Bahkan jika Anda menggunakan deklarasi XML dan/atau XHTML doctype, _ _ lama <IE masih mengurai dokumen sebagai HTML biasa. Dan dalam HTML biasa, sintaksis yang menutup sendiri tidak didukung. Garis miring trailing hanya diabaikan, Anda harus menggunakan tag penutup eksplisit.

Bahkan browser dengan dukungan untuk penguraian XHTML, seperti IE 9 dan yang lebih bar , masih akan mengurai dokumen sebagai HTML kecuali Anda melayani dokumen dengan tipe konten XML. Tetapi dalam kasus lama IE tidak akan menampilkan dokumen sama sekali!

44
JacquesB

Orang-orang di atas sudah cukup banyak menjelaskan masalah ini, tetapi satu hal yang mungkin membuat semuanya menjadi jelas adalah bahwa, meskipun orang menggunakan <br/> dan demikian sepanjang waktu dalam dokumen HTML, / dalam posisi seperti itu pada dasarnya diabaikan, dan hanya digunakan ketika mencoba untuk membuat sesuatu yang dapat diuraikan seperti XML dan HTML. Coba <p/>foo</p>, misalnya, dan Anda mendapatkan paragraf reguler.

26
Marijn

Tag skrip penutup otomatis tidak berfungsi, karena tag skrip dapat berisi kode sebaris, dan HTML tidak cukup pintar untuk mengaktifkan atau menonaktifkan fitur tersebut berdasarkan keberadaan atribut.

Di sisi lain, HTML memang memiliki tag yang sangat baik untuk menyertakan referensi ke sumber daya luar: tag <link>, dan itu bisa menutup sendiri. Ini sudah digunakan untuk memasukkan stylesheet, RSS dan Atom feed, URI kanonik, dan segala macam barang lainnya. Kenapa tidak JavaScript?

Jika Anda ingin tag skrip tertutup sendiri, Anda tidak dapat melakukannya seperti yang saya katakan, tetapi ada alternatifnya, meskipun bukan yang cerdas. Anda dapat menggunakan tag tautan penutup otomatis dan tautan ke JavaScript Anda dengan memberikannya jenis teks/javascript dan rel sebagai skrip, seperti di bawah ini:

<link type="text/javascript" rel ="script" href="/path/tp/javascript" />
22
defau1t

Tidak seperti XML dan XHTML, HTML tidak memiliki pengetahuan tentang sintaksis yang menutup sendiri. Browser yang menafsirkan XHTML sebagai HTML tidak tahu bahwa karakter / menunjukkan bahwa tag harus ditutup sendiri; alih-alih mereka menafsirkannya seperti atribut kosong dan parser masih menganggap tag itu 'terbuka'.

Sama seperti <script defer> diperlakukan sebagai <script defer="defer">, <script /> diperlakukan sebagai <script /="/">.

20
rpetrich

Internet Explorer 8 dan yang lebih lama tidak mendukung tipe MIME yang tepat untuk XHTML, application/xhtml+xml. Jika Anda menjalankan XHTML sebagai text/html, yang harus Anda lakukan untuk Internet Explorer versi lama ini untuk melakukan apa saja, itu akan ditafsirkan sebagai HTML 4.01. Anda hanya dapat menggunakan sintaks pendek dengan elemen apa pun yang memungkinkan tag penutup dihilangkan. Lihat Spesifikasi HTML 4.01 .

XML 'short form' ditafsirkan sebagai atribut bernama /, yang (karena tidak ada tanda sama dengan) ditafsirkan memiliki nilai implisit "/". Ini benar-benar salah dalam HTML 4.01 - atribut yang tidak dideklarasikan tidak diizinkan - tetapi browser akan mengabaikannya.

IE9 dan yang lebih baru mendukung XHTML 5 disajikan dengan application/xhtml+xml.

18
Mike Dimmick

Itu karena TAG SCRIPT bukan ELEMEN YANG BISA.

Dalam Dokumen HTML - ELEMEN VOID tidak memerlukan "tag penutup" sama sekali!

Di xhtml , semuanya Generik, oleh karena itu mereka semua membutuhkan terminasi mis. sebuah "tag penutup"; Termasuk br, penghentian baris sederhana, seperti <br></br> atau steno <br />.

Namun, Elemen Skrip tidak pernah menjadi Elemen batal atau parametrik, karena tag skrip sebelum yang lainnya, adalah Instruksi Peramban, bukan deklarasi Deskripsi Data.

Pada prinsipnya, Instruksi Pengakhiran Semantik misalnya, "tag penutup" hanya diperlukan untuk memproses instruksi yang semantiknya tidak dapat diakhiri oleh tag yang berhasil. Contohnya:

<H1> semantik tidak dapat diakhiri oleh <P> berikut karena tidak membawa cukup banyak semantiknya sendiri untuk ditimpa dan karenanya menghentikan set instruksi H1 sebelumnya. Meskipun akan dapat memecah stream menjadi baris paragraf baru, itu tidak "cukup kuat" untuk mengesampingkan ukuran font saat ini & ketinggian garis gaya menuangkan down the stream , yaitu bocor dari H1 (karena P tidak memilikinya).

Ini adalah bagaimana dan mengapa pensinyalan "/" (terminasi) telah ditemukan.

Tag terminasi generik tanpa-deskripsi seperti < />, akan mencukupi untuk setiap jatuh tunggal dari kaskade yang ditemui, misalnya: <H1>Title< /> tapi itu tidak selalu terjadi, karena kami juga ingin dapat "bersarang", beberapa penandaan perantara Stream: dibagi menjadi torrents sebelum membungkus/jatuh ke kaskade lain. Sebagai akibatnya terminator generik seperti < /> tidak akan dapat menentukan target properti untuk diakhiri. Misalnya: <b>tebal<i> tebal-miring < /> italic </>normal. Tidak diragukan lagi akan gagal untuk mendapatkan maksud kami dengan benar dan kemungkinan besar akan menafsirkannya sebagai bold bold-itallic bold normal.

Ini adalah bagaimana gagasan dari pembungkus mis., Wadah lahir. (Gagasan ini sangat mirip sehingga tidak mungkin untuk membedakan dan kadang-kadang elemen yang sama dapat memiliki keduanya. <H1> keduanya pembungkus dan wadah pada saat yang sama. Sedangkan <B> hanya pembungkus semantik). Kita akan membutuhkan wadah polos, tidak ada semantik. Dan tentu saja penemuan Unsur DIV datang.

Elemen DIV sebenarnya adalah 2BR-Container. Tentu saja kedatangan CSS membuat situasi lebih aneh daripada yang seharusnya terjadi dan menyebabkan kebingungan besar dengan banyak konsekuensi besar - secara tidak langsung!

Karena dengan CSS, Anda dapat dengan mudah mengganti perilaku pra & setelah asli dari DIV yang baru ditemukan, sering disebut sebagai "wadah apa-apa". Yang tentu saja salah! DIV adalah elemen blok dan akan secara alami memutus garis aliran baik sebelum dan sesudah pensinyalan akhir. Segera WEB mulai menderita halaman DIV-itis. Sebagian besar masih.

Datangnya CSS dengan kemampuannya untuk sepenuhnya menimpa dan sepenuhnya mendefinisikan kembali perilaku asli dari setiap Tag HTML, entah bagaimana berhasil membingungkan dan mengaburkan seluruh makna keberadaan HTML ...

Tiba-tiba semua tag HTML muncul seolah-olah usang, mereka rusak, dilucuti dari semua makna, identitas, dan tujuan aslinya. Entah bagaimana Anda akan mendapatkan kesan bahwa mereka tidak lagi diperlukan. Mengatakan: Tag wadah-pembungkus tunggal akan cukup untuk semua presentasi data. Cukup tambahkan atribut yang diperlukan. Mengapa tidak memiliki tag yang bermakna sebagai gantinya; Ciptakan nama tag saat Anda pergi dan biarkan CSS yang mengganggu.

Inilah bagaimana xhtml dilahirkan dan tentu saja tumpul besar, dibayar sangat mahal oleh pendatang baru dan visi yang menyimpang dari apa itu apa, dan apa tujuan sialan itu semua. W3C pergi dari World Wide Web ke What Went Wrong, Kamerad? !!

Tujuan HTML adalah ntuk melakukan streaming data yang bermakna bagi penerima manusia.

Untuk menyampaikan Informasi.

Bagian formal ada di sana hanya untuk membantu kejelasan pengiriman informasi. xhtml tidak memberikan sedikit pun pertimbangan untuk informasi tersebut. - Untuk itu, informasi itu sama sekali tidak relevan.

Hal yang paling penting dalam masalah ini adalah untuk mengetahui dan dapat memahami bahwa xhtml bukan hanya versi dari beberapa HTML yang diperluas, xhtml adalah binatang yang sama sekali berbeda; alasan; dan karenanya sebaiknya memisahkannya.

5
Bekim Bacaj

Perbedaan antara 'true XHTML', 'faux XHTML' dan HTML serta pentingnya tipe MIME yang dikirim ke server telah sudah dijelaskan di sini juga . Jika Anda ingin mencobanya sekarang, berikut ini cuplikan sederhana yang dapat diedit dengan pratinjau langsung termasuk tag skrip yang ditutup sendiri untuk peramban yang mampu:

div { display: flex; }
div + div {flex-direction: column; }
<div>Mime type: <label><input type="radio" onchange="t.onkeyup()" id="x" checked  name="mime"> application/xhtml+xml</label>
<label><input type="radio" onchange="t.onkeyup()" name="mime"> text/html</label></div>
<div><textarea id="t" rows="4" 
onkeyup="i.src='data:'+(x.checked?'application/xhtml+xml':'text/html')+','+encodeURIComponent(t.value)"
><?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
[<!ENTITY x "true XHTML">]>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
  <p>
    <span id="greet" swapto="Hello">Hell, NO :(</span> &x;.
    <script src="data:text/javascript,(g=document.getElementById('greet')).innerText=g.getAttribute('swapto')" />
    Nice to meet you!
    <!-- 
      Previous text node and all further content falls into SCRIPT element content in text/html mode, so is not rendered. Because no end script tag is found, no script runs in text/html
    -->
  </p>
</body>
</html></textarea>

<iframe id="i" height="80"></iframe>

<script>t.onkeyup()</script>
</div>

Anda harus melihat Hello, true XHTML. Nice to meet you! di bawah textarea.

Untuk browser yang tidak mampu, Anda dapat menyalin konten textarea dan menyimpannya sebagai file dengan ekstensi .xhtml (atau .xht) ( terima kasih Alek untuk petunjuk ini ).

2
myf