Apakah saya benar-benar harus menyandikan '&' sebagai '& amp;'?

207

Saya menggunakan &simbol ' ' dengan HTML5 dan UTF-8 di situs saya <title>. Google menunjukkan ampersand fine pada SERPnya, seperti halnya semua browser dalam judulnya.

http://validator.w3.org memberi saya ini:

& tidak memulai referensi karakter. (& mungkin seharusnya lolos sebagai &amp;.)

Apakah saya benar-benar perlu melakukannya &amp;?

Saya tidak peduli tentang halaman saya yang validasi demi validasi, tapi saya ingin tahu pendapat orang tentang ini dan apakah itu penting dan mengapa.

Haroldo
sumber
63
Spesifikasi tidak mengatakan demikian. Poster mengacu pada HTML5 yang tidak memerlukan pelepasan ampersand di semua skenario.
Matthew Wilson
2
Ini harus Wiki Komunitas, saat Anda mencari pendapat, dan tidak rewel tentang validasi menyiratkan bahwa tidak ada dasar obyektif untuk menjawab.
Richard JP Le Guen
6
@ Richard: benarkah? Meskipun saya tidak setuju bahwa "validasi tidak masalah", saya melihat ini sebagai pertanyaan yang sangat objektif: "apakah ini melanggar selain spec?"
Joachim Sauer
2
@YiJiang Browser web saat ini berusaha keras untuk memahami pengguna . Begitu juga Google . Itu bagian dari Spec. Browser web di masa depan mungkin kurang memaafkan. Jadi selalu ide yang baik untuk memeriksa bagaimana Wikipedia melakukannya, dan menyalinnya.
unixman83
2
Spesifikasi HTML mengatakan untuk menerima input sampah. Apakah itu berarti situs Anda "diizinkan" menjadi omong kosong sekarang? Tutup tag yang perlu ditutup dan melarikan diri! Ayo orang-orang.
doug65536

Jawaban:

143

Iya. Seperti yang dikatakan kesalahan, dalam HTML, atribut adalah #PCDATA yang berarti mereka diuraikan. Ini berarti Anda dapat menggunakan entitas karakter dalam atribut. Menggunakan &dengan sendirinya adalah salah dan jika bukan untuk browser yang lunak dan fakta bahwa ini adalah HTML bukan XHTML, akan memecah parsing. Lari saja &amp;dan semuanya akan baik-baik saja.

HTML5 memungkinkan Anda untuk membiarkannya tidak dihapus, tetapi hanya ketika data yang mengikuti tidak terlihat seperti referensi karakter yang valid. Namun, lebih baik melarikan diri dari semua contoh simbol ini daripada khawatir tentang mana yang seharusnya dan mana yang tidak perlu.

Ingatlah hal ini; jika Anda tidak melarikan diri & ke & amp ;, itu cukup buruk untuk data yang Anda buat (di mana kode itu mungkin tidak valid), Anda mungkin juga tidak melarikan diri dari pembatas tag, yang merupakan masalah besar untuk data yang dikirimkan pengguna, yang bisa mengarah ke injeksi HTML dan skrip, pencurian cookie, dan eksploitasi lainnya.

Tolong lepas kode Anda. Ini akan menghemat banyak masalah di masa depan.

Delan Azabani
sumber
9
Tidak ada browser yang akan "salah menafsirkan" & dengan sendirinya. Setiap browser yang ada menampilkannya sebagai "&". Mengingat dia secara eksplisit meminta alasan praktis untuk melakukannya, dan dia menyatakan bahwa dia tidak peduli dengan validasi ..
Thomas Bonini
47
Iya. Namun secara moral, haruskah kita mengandalkan kelonggaran dan penanganan kesalahan "baik" dari peramban? Atau haruskah kita menulis kode yang benar?
Delan Azabani
8
@Delan: ketika saya mencoba membuat setiap halaman yang saya tulis valid, saya mengerti dari membaca pertanyaannya bahwa dia tidak peduli dengan "moral". Dia hanya peduli apakah itu berhasil atau tidak. Mereka adalah dua filosofi yang berbeda dan keduanya memiliki pro dan kontra, dan tidak ada yang "benar". Misalnya situs web ini tidak valid, dan ini situs web yang bagus.
Thomas Bonini
3
@Andreas, tetapi browser memiliki cukup banyak bug dalam cara mereka menafsirkan kode yang benar, tergantung pada mereka mendapatkan hasil yang tepat ketika Anda mengirim mereka markup yang tidak berarti adalah untung-untungan. Mungkin berhasil hari ini dengan contoh itu, dan kemudian gagal dengan contoh berikutnya (katakan jika contoh berikutnya memiliki titik koma di suatu tempat setelah &)
Jon Hanna
11
Semua orang tampaknya berbicara tentang HTML5, tetapi pertanyaan aslinya menyatakan bahwa HTML5 sedang digunakan. HTML5 secara eksplisit memungkinkan unescaped & dalam situasi ini, kecuali apa yang mengikuti & biasanya berkembang ke entitas (misalnya & copy = 2 bermasalah tetapi & x = 2 baik-baik saja).
Matthew Wilson
55

Selain validasi, faktanya tetap bahwa penyandian karakter tertentu penting untuk dokumen HTML sehingga dapat di-render dengan benar dan aman sebagai halaman web.

Pengkodean &seperti &amp;dalam semua keadaan, bagi saya, adalah aturan yang lebih mudah untuk dijalani, mengurangi kemungkinan kesalahan dan kegagalan.

Bandingkan yang berikut ini: mana yang lebih mudah? mana yang lebih mudah diganggu ?

Metodologi 1

  1. Tulis beberapa konten yang menyertakan karakter ampersand.
  2. Encode semuanya.

Metodologi 2

(dengan sebutir garam, tolong;))

  1. Tulis beberapa konten yang menyertakan karakter ampersand.
  2. Atas dasar kasus per kasus, lihat masing-masing ampersand. Tentukan apakah:
    • Itu terisolasi, dan dengan demikian jelas sebuah ampersand. misalnya. volt & amp
       > Dalam hal itu jangan repot-repot meng-encode-nya.
    • Itu tidak terisolasi, tetapi Anda merasa itu tetap tidak ambigu, karena entitas yang dihasilkan tidak ada dan tidak akan pernah ada karena daftar entitas tidak akan pernah berevolusi. mis. amp&volt
       > Dalam hal itu jangan repot-repot menyandikannya.
    • Itu tidak terisolasi, dan ambigu. misalnya.volt&amp
       > Encode.

??

Richard JP Le Guen
sumber
3
Kasus kedua amp&volt adalah ambigu: Apakah &voltsekarang referensi entitas atau tidak?
Gumbo
6
@Gumbo The ampersand di amp&voltadalah tidak ampersand ambigu (sesuai definisi dalam HTML spec). Lihat mathiasbynens.be/notes/ambiguous-ampersand dan mothereff.in/ampersands#amp%26volt .
Mathias Bynens
@MathiasBynens Sampai sekarang (2019), definisi dari ampersand yang ambigu tampaknya telah sedikit berubah dari definisi yang Anda kutip di 2011 di mathiasbynens.be/notes/ambiguous-ampersands .
Jacob C. mengatakan Reinstate Monica
21

Aturan HTML5 berbeda dari HTML4. Ini tidak diperlukan dalam HTML5 - kecuali jika ampersand sepertinya memulai nama parameter. "& copy = 2" masih menjadi masalah, misalnya, karena & salin; adalah simbol hak cipta.

Namun menurut saya itu lebih sulit untuk memutuskan untuk menyandikan atau tidak untuk menyandikan tergantung pada teks berikut. Jadi jalur termudah mungkin adalah menyandikan sepanjang waktu.

Matthew Wilson
sumber
2
Ini seperti mengutip nilai atribut - Anda tidak harus melakukannya, tetapi Anda tidak dapat salah jika melakukannya sepanjang waktu.
Paul D. Waite
3
&copy=2bukan masalah besar seperti yang Anda pikirkan. Dalam nilai atribut (misalnya hrefatribut), &copytidak akan dianggap sebagai referensi karakter ©. Di luar nilai atribut, itu akan.
Mathias Bynens
Mengingat bahwa ampersand biasanya didahului dan diikuti oleh spasi dalam teks bahasa Inggris, tidak sulit untuk mengingat atau memikirkan aturan yang saya ikuti: Jika ampersand tidak menyentuh karakter lain yang terlihat, yang hampir selalu, maka itu tidak perlu encoding. Jika tidak, cukup enkode demi kesederhanaan.
Carl Smith
Bisakah Anda menambahkan referensi ke aturan HTML5?
Ferrybig
17

Saya pikir ini telah berubah menjadi lebih banyak pertanyaan tentang "mengapa mengikuti spesifikasi ketika browser tidak peduli." Inilah jawaban umum saya:

Standar bukanlah hal yang "sekarang". Mereka adalah "masa depan". Jika kita, sebagai pengembang, mengikuti standar web, maka vendor peramban lebih cenderung menerapkan standar itu dengan benar, dan kami bergerak lebih dekat ke web yang sepenuhnya dapat dioperasikan, di mana peretasan CSS, deteksi fitur, dan deteksi peramban tidak diperlukan. Di mana kita tidak perlu mencari tahu mengapa tata letak kita pecah di browser tertentu, atau bagaimana cara mengatasinya.

Khususnya, jika HTML5 tidak perlu menggunakan & amp; dalam situasi spesifik Anda, dan Anda menggunakan doctype HTML5 (dan juga mengharapkan pengguna Anda menggunakan browser yang sesuai dengan HTML5), maka tidak ada alasan untuk melakukannya.

Ryan Kinal
sumber
1
Dengan itu dikatakan, secara umum, Anda harus ingat bahwa sebagian besar cara "standar" masih dalam mode konsep dan dapat berubah di masa depan.
refaelio
6

Nah, jika itu berasal dari input pengguna maka benar-benar ya, untuk alasan yang jelas. Pikirkan jika situs web ini tidak melakukannya: judul pertanyaan ini akan muncul sebagaimana saya benar-benar harus menyandikan '&' sebagai '&'?

Jika itu hanya sesuatu seperti echo '<title>Dolce & Gabbana</title>';maka dengan tegas Anda tidak perlu. Akan lebih baik, tetapi jika Anda tidak, pengguna akan melihat perbedaannya.

Thomas Bonini
sumber
5

Bisakah Anda menunjukkan kepada kami apa titlesebenarnya milik Anda ? Saat saya kirim

<!DOCTYPE html>
<html>
<title>Dolce & Gabbana</title>
<body>
<p>am i allowed loose & mpersands?</p>
</body>
</html>

ke http://validator.w3.org/ - secara eksplisit memintanya untuk menggunakan mode HTML 5 eksperimental - ia tidak memiliki keluhan tentang &...

AakashM
sumber
1
Ya, HTML5 memiliki parser yang berbeda dari parser HTML dan XHTML sebelumnya, dan memungkinkan ampersand yang tidak terhapuskan dalam situasi tertentu.
kevinji
Sejauh contoh-contoh ini pergi, ini bukan hal baru di HTML5. Keduanya <title>Dolce & Gabbana</title>dan <p>Dolce & Gabbana</p>adalah HTML 2.0 yang valid.
Mathias Bynens
4

Dalam HTML a &menandai awal referensi, baik referensi karakter atau referensi entitas . Dari titik itu pada parser mengharapkan salah satu yang #menunjukkan referensi karakter, atau nama entitas yang menunjukkan referensi entitas, keduanya diikuti oleh a ;. Itu perilaku normal.

Tetapi jika nama referensi atau hanya pembukaan referensi &diikuti dengan spasi putih atau pembatas lainnya seperti ", ', <, >, &, ending ;dan bahkan referensi untuk mewakili polos &dapat dihilangkan:

<p title="&amp;">foo &amp; bar</p>
<p title="&amp">foo &amp bar</p>
<p title="&">foo & bar</p>

Hanya dalam kasus ini, akhir ;atau bahkan referensi itu sendiri dapat dihilangkan (setidaknya dalam HTML 4). Saya pikir HTML 5 membutuhkan akhir ;.

Tetapi spesifikasi merekomendasikan untuk selalu menggunakan referensi seperti referensi karakter &#38;atau referensi entitas &amp;untuk menghindari kebingungan:

Penulis harus menggunakan " &amp;" (ASCII desimal 38) alih-alih " &" untuk menghindari kebingungan dengan permulaan referensi karakter (pembatas entitas referensi terbuka). Penulis juga harus menggunakan " &amp;" dalam nilai atribut karena referensi karakter diizinkan dalam nilai atribut CDATA.

Gumbo
sumber
1
Itulah spesifikasi HTML 4 yang Anda tautkan; dari pembacaan saya tentang (konsep) HTML 5 spec, hanya ampersand ambigu yang tidak diizinkan. Sebuah ampersand diikuti oleh spasi, misalnya, tidak ambigu, dan karenanya (lagi dengan pembacaan saya) harus diizinkan - lihat jawaban saya untuk markup yang diterima validator HTML 5.
AakashM
1
@ AashashM: Saya tidak yakin, itu terdengar seperti itu.
Gumbo
3

Jika pengguna memberikannya kepada Anda, atau URL itu akan berakhir, Anda harus menghindarinya.

Jika muncul dalam teks statis pada halaman? Semua browser akan mendapatkan yang ini dengan benar, Anda tidak perlu khawatir, karena ini akan berhasil.

Dean J
sumber
3

Pembaruan (Maret 2020): Validator W3C tidak lagi mengeluh tentang melarikan diri URL.

Saya sedang memeriksa mengapa URL Gambar harus diloloskan, karenanya saya mencobanya di https://validator.w3.org . Penjelasannya cukup bagus. Ini menyoroti bahwa bahkan URL harus diloloskan. [PS: Saya kira itu akan dihapus ketika dikonsumsi karena kebutuhan URL &. Adakah yang bisa menjelaskan?]

<img alt="" src="foo?bar=qut&qux=fop" />

Referensi entitas ditemukan dalam dokumen, tetapi tidak ada referensi dengan nama yang ditentukan. Seringkali ini disebabkan oleh salah mengeja nama referensi, ampersand tanpa kode, atau dengan meninggalkan tanda titik koma (;). Penyebab paling umum dari kesalahan ini adalah ampersand yang tidak terenkripsi dalam URL seperti yang dijelaskan oleh WDG di "Ampersands in URLs". Referensi entitas mulai dengan ampersand (&) dan diakhiri dengan tanda titik koma (;). Jika Anda ingin menggunakan ampers literal dan dalam dokumen Anda, Anda harus menyandikannya sebagai "&" (bahkan di dalam URL!). Berhati-hatilah untuk mengakhiri referensi entitas dengan titik koma atau referensi entitas Anda dapat ditafsirkan sehubungan dengan teks berikut. Juga perlu diingat bahwa referensi entitas yang bernama case-sensitive; & Aelig; dan æ adalah karakter yang berbeda.

Nishant
sumber
1
Baca jawaban terpilih. Atribut adalah #PCDATA dan karenanya diuraikan. Entitas ditangani di sana. Dalam contoh Anda, &mulai referensi entitas. Setelah membaca &qux, parser tidak menemukan titik koma akhir ( ;), tetapi berjalan ke tanda sama dengan ( =), yang tidak dapat menjadi bagian dari nama entitas. Ini harus menjadi kesalahan parse, jika parser berusaha menjadi sangat ketat (sesuai dengan HTML 4). Di HTML 5, entitas parsing secara keseluruhan lebih santai.
Palec
1
Saya menduga bahwa secara umum sebaiknya digunakan ;sebagai pemisah dalam string kueri (saat Anda mengontrol tautan) karena alasan itu.
Demi
2

Ya, Anda harus mencoba menyajikan kode yang valid jika memungkinkan.

Sebagian besar browser akan memperbaiki kesalahan ini secara diam-diam, tetapi ada masalah dengan mengandalkan penanganan kesalahan di browser. Tidak ada standar untuk bagaimana menangani kode yang salah, jadi terserah masing-masing vendor browser untuk mencoba mencari tahu apa yang harus dilakukan dengan setiap kesalahan, dan hasilnya dapat bervariasi.

Beberapa contoh di mana browser cenderung bereaksi berbeda adalah jika Anda meletakkan elemen di dalam tabel tetapi di luar sel tabel, atau jika Anda membuat tautan di dalam sarang.

Untuk contoh spesifik Anda, kemungkinan besar tidak akan menimbulkan masalah, tetapi koreksi kesalahan pada peramban mungkin misalnya menyebabkan peramban berubah dari mode yang memenuhi standar menjadi mode quirks, yang dapat membuat tata letak Anda rusak sepenuhnya.

Jadi, Anda harus memperbaiki kesalahan seperti ini dalam kode, jika bukan karena hal lain, maka singkatkan daftar kesalahan di validator, sehingga Anda dapat menemukan masalah yang lebih serius.

Guffa
sumber
2

Beberapa tahun yang lalu, kami mendapat laporan bahwa salah satu aplikasi web kami tidak ditampilkan dengan benar di Firefox. Ternyata halaman itu berisi tag yang terlihat seperti

<div style="..." ... style="...">

Ketika dihadapkan dengan atribut gaya berulang, IE menggabungkan kedua gaya, sementara Firefox hanya menggunakan salah satu dari mereka, maka perilaku yang berbeda. Saya mengubah tag menjadi

<div style="...; ..." ...>

dan tentu saja, itu memperbaiki masalah! Moral dari cerita ini adalah bahwa browser memiliki lebih konsisten menangani HTML yang valid daripada HTML yang tidak valid. Jadi, perbaiki markup sialanmu! (Atau gunakan HTML Tidy untuk memperbaikinya.)

dan04
sumber
1

jika &digunakan dalam html maka Anda harus menghindarinya

Jika &digunakan dalam string javascript misalnya sebuah alert('This & that');atau document.href Anda tidak perlu menggunakannya.

Jika Anda menggunakan document.write maka Anda harus menggunakannya misalnya document.write(<p>this &amp; that</p>)

Alex
sumber
document.writeharus dihindari. Lihat kotak peringatan di w3.org/html/wg/drafts/html/master/dom.html#document.write%28%29
Oriol
Poin bagus tentang document.write(). Tetapi yang paling penting Alex membuat tentang menulis ke dokumen dari skrip berdiri, imo. +1
Patrick M
1

Itu tergantung pada kemungkinan titik koma berakhir di dekat Anda &, menyebabkannya menampilkan sesuatu yang sangat berbeda.

Misalnya, ketika berurusan dengan input dari pengguna (misalnya, jika Anda memasukkan subjek yang disediakan pengguna dari posting forum di tag judul Anda), Anda tidak pernah tahu di mana mereka mungkin meletakkan tanda koma acak, dan itu mungkin secara acak menampilkan entitas aneh. Jadi selalu melarikan diri dalam situasi itu.

Untuk html statis Anda sendiri, tentu saja, Anda dapat melewatinya, tetapi sangat sepele untuk menyertakan pelarian yang benar, sehingga tidak ada alasan yang baik untuk menghindarinya.

Douglas
sumber
0

Jika Anda benar-benar berbicara tentang teks statis

<title>Foo & Bar</title>

disimpan dalam beberapa file di hard disk dan dilayani langsung oleh server, maka ya: itu mungkin tidak perlu diloloskan.

Namun, karena ada sangat sedikit konten HTML saat ini yang sepenuhnya statis, saya akan menambahkan penafian berikut yang mengasumsikan bahwa konten HTML dihasilkan dari beberapa sumber lain (konten basis data, input pengguna, hasil panggilan layanan web, hasil legacy API,. ..):

Jika Anda tidak melarikan diri dari yang sederhana &, maka kemungkinan Anda juga tidak melarikan diri a &amp;atau a &nbsp;atau <b>atau <script src="http://attacker.com/evil.js">atau teks tidak valid lainnya. Itu berarti bahwa Anda paling baik menampilkan konten Anda secara salah dan kemungkinan besar lebih rentan terhadap serangan XSS .

Dengan kata lain: ketika Anda sudah memeriksa dan melarikan diri dari kasus-kasus lain yang lebih bermasalah, maka hampir tidak ada alasan untuk meninggalkan standalone yang tidak-sepenuhnya-rusak-tetapi-masih-agak mencurigakan- & tidak terhindar.

Joachim Sauer
sumber
2
Saya tidak downvote tetapi, jika saya harus menebak, saya akan mengatakan Anda downvoted karena jawaban Anda (sementara cerdas) sedikit tidak cocok dengan pertanyaan. Dia tidak bertanya tentang keluar dari input pengguna. Dia memiliki kontrol atas karakter dan pada dasarnya bertanya "Jika itu melakukan apa yang saya inginkan, apakah benar-benar penting untuk mengikuti spesifikasi bahasa ke surat itu?" Yaitu, dia tahu ada & karena dia memasukkannya.
Matt
@ Matt: Begitu, dan itu masuk akal. Saya hanya berasumsi bahwa tidak ada yang menulis halaman HTML sepenuhnya statis lagi dan bahwa hampir semua konten setidaknya agak dinamis (biasanya didasarkan pada beberapa konten basis data). Mungkin asumsi itu seharusnya dibuat eksplisit.
Joachim Sauer
-1

tidak yakin apakah ini berguna bagi siapa pun ... Saya sedang memperjuangkan ini untuk sementara waktu ... di sini adalah regex mulia yang dapat Anda gunakan untuk memperbaiki semua tautan, javascript, konten Anda. Saya harus berurusan dengan satu ton konten warisan yang tidak seorang pun ingin memperbaikinya.

Tambahkan ini ke override Render Anda di halaman master Anda atau kontrol:

Tolong jangan nyalakan saya karena meletakkan ini di tempat yang salah:

// remove the & from href="blaw?a=b&b=c" and replace with &amp; 
//in urls - this corrects any unencoded & not just those in URL's
// this match will also ignore any matches it finds within <script> blocks AND
// it will also ignore the matches where the link includes a javascript command like
// <a href="javascript:alert{'& & &'}">blaw</a>
html = Regex.Replace(html, "&(?!(?<=(?<outerquote>[\"'])javascript:(?>(?!\\k<outerquote>|[>]).)*)\\k<outerquote>?)(?!(?:[a-zA-Z][a-zA-Z0-9]*|#\\d+);)(?!(?>(?:(?!<script|\\/script>).)*)\\/script>)", "&amp;", RegexOptions.Singleline | RegexOptions.IgnoreCase);
Richard Dufour
sumber
-1

Link memiliki contoh yang cukup baik dari kapan dan mengapa Anda mungkin perlu untuk melarikan diri &ke&amp;

https://jsfiddle.net/vh2h7usk/1/

Menariknya, saya harus melarikan diri dari karakter agar dapat mewakili dengan benar dalam jawaban saya di sini. Jika saya menggunakan opsi contoh kode bawaan (dari panel jawaban), saya bisa mengetik &amp;dan muncul sebagaimana mestinya. Tetapi jika saya harus menggunakan <code></code>elemen secara manual , maka saya harus melarikan diri untuk mewakilinya dengan benar :)

mathin
sumber