Apakah saya menyandikan ampersand di <a href…>?

157

Saya menulis kode yang secara otomatis menghasilkan HTML, dan saya ingin menyandikannya dengan benar.

Katakanlah saya sedang membuat tautan ke URL berikut:

http://www.google.com/search?rls=en&q=stack+overflow

Saya berasumsi bahwa semua nilai atribut harus dikodekan-HTML. (Tolong koreksi saya jika saya salah.) Jadi itu berarti jika saya meletakkan URL di atas ke dalam jangkar tag, saya harus menyandikan ampersand sebagai &amp;, seperti ini:

<a href="http://www.google.com/search?rls=en&amp;q=stack+overflow">

Apakah itu benar?

JW.
sumber
kemungkinan duplikat karakter mana yang membuat URL tidak valid?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
6
@CiroSantilli: itu tentang string URL aktual; ini tentang bagaimana mereka dikodekan ketika mereka muncul dalam atribut HTML.
JW.
seperti yang saya lihat, pengkodean ampersand tidak selalu diperlukan di html5, dan jawaban sudah usang.
qdinar
1
pertanyaan untuk html5: stackoverflow.com/questions/19441750/…
qdinar

Jawaban:

175

Ya itu. Entitas HTML diuraikan di dalam atribut HTML, dan nyasar &akan menciptakan ambiguitas. Itu sebabnya Anda harus selalu menulis, &amp;bukan hanya &di dalam semua atribut HTML.

Yang mengatakan, hanya &dan kutipan perlu dikodekan. Jika Anda memiliki karakter khusus seperti épada atribut Anda, Anda tidak perlu menyandikannya untuk memenuhi parser HTML.

Dulu, URL membutuhkan perlakuan khusus dengan karakter non-ASCII é. Anda harus menyandikan mereka yang menggunakan persen-lolos, dan dalam hal ini akan memberikan %C3%A9, karena mereka ditentukan oleh RFC 1738 . Namun, RFC 1738 telah digantikan oleh RFC 3986 (URI, Uniform Resource Identifiers) dan RFC 3987 (IRI, Pengidentifikasi Sumberdaya Internasional), di mana WhatWG mendasarkan pekerjaannya untuk menentukan bagaimana peramban harus berperilaku ketika mereka melihat URL dengan non-ASCII karakter di dalamnya sejak HTML5 . Karenanya sekarang aman untuk memasukkan karakter non-ASCII dalam URL, yang disandikan atau tidak.

zneak
sumber
1
Saya cukup yakin akan hal ini, tetapi saya memiliki momen keraguan yang langka. Terimakasih sudah mengkonfirmasi.
JW.
1
Anda juga dapat menyandikan spasi sebagai "+" daripada% 20 - yang membuat URL lebih mudah dibaca.
NickG
1
+ tidak dihormati di tautan mailto di klien email asli iPhone saat ini, apa pun nilainya.
Ryan Olson
1
émasih membutuhkan pengodean: stackoverflow.com/questions/2742852/unicode-characters-in-urls
lulalala
4
Saya akan menambahkan (karena saya baru saja jatuh ke dalam kesalahan ini) bahwa jika Anda mengandalkan mesin template Anda harus memeriksa apakah itu secara otomatis mengurus melarikan diri entitas HTML atau tidak. Dalam kasus saya, Twig melakukan itu, dan saya salah menulis dua kali &amp;ke atribut tag daripada menggunakan secara langsung &.
Kamafeather
24

Dengan rekomendasi HTML resmi saat ini, ampersand harus diloloskan misalnya seperti &amp;dalam konteks seperti ini. Namun, browser tidak memerlukannya, dan HTML5 CR mengusulkan untuk membuat aturan ini , sehingga aturan khusus berlaku dalam nilai atribut. Validator HTML5 saat ini sudah ketinggalan zaman dalam hal ini (lihat laporan bug dengan komentar).

Akan tetap memungkinkan untuk keluar dari ampersand dalam nilai atribut, tetapi selain validasi dengan alat saat ini, tidak ada kebutuhan praktis untuk menghindarinya dalam hrefnilai (dan ada risiko kecil membuat kesalahan jika Anda mulai melarikan diri dari mereka).

Jukka K. Korpela
sumber
4
XHTML ( nyata XHTML dikirim sebagai application/xhtml+xml) kemungkinan besar akan selalu membutuhkan itu, meskipun.
zneak
4
Satu peringatan untuk perubahan ini, yang masih sedang dibahas, diperdebatkan, dan disalahpahami, adalah bahwa &itu seharusnya baik-baik saja sekarang, selama itu " tidak ambigu". Salah satu cara yang jelas untuk membuat ampers dan ambigu adalah mengikutinya terlebih dahulu dengan karakter non-spasi dan kemudian titik koma. Ampersand itu sekarang ambigu, dan akan menyebabkan kesalahan parse.
matty
Seperti yang dikatakan Jukka, tentu saja ada risiko untuk menyandikan semua ampersand, jadi pertimbangkan seberapa besar kemungkinan salah satu url href Anda mengandung tanda titik koma. Agak tidak mungkin, karena saya tidak yakin pernah melihat url dengan tanda titik koma. Bukannya itu tidak bisa dilakukan. Jadi secara praktis, saya tidak berpikir kemungkinan penggunaan kita &akan ambigu. Oleh karena itu, kami terus menggunakannya tanpa atribut dalam atribut href.
matty
Seluruh alasan pelarian itu diperlukan justru karena kemungkinan ambiguitas . Masalah khusus ini mungkin tidak memperkenalkan vektor serangan XSS, rendering yang buruk, atau pengaruh apa pun pada 99,99% dari waktu, tetapi itu bukan alasan untuk tidak repot-repot. Melakukan melarikan diri dengan benar itu sulit dan selalu ada kemungkinan membuat kesalahan.
Phil
5

Saya memposting jawaban baru karena saya menemukan jawaban zneak tidak memiliki cukup contoh, tidak menunjukkan penanganan HTML dan URI sebagai aspek dan standar yang berbeda dan ada beberapa hal kecil yang hilang.

Anda memiliki dua standar tentang URL di tautan ( <a href).

Standar pertama adalah RFC 1866 (HTML 2.0) di mana dalam "3.2.1. Data Characters" Anda dapat membaca karakter yang harus diloloskan ketika digunakan sebagai nilai untuk atribut HTML. (Atribut sendiri tidak memungkinkan karakter khusus sama sekali, misalnya <a hr&ef="http://...tidak diizinkan, juga tidak <a hr&amp;ef="http://....)

Kemudian ini telah masuk ke standar HTML 4 , karakter yang Anda butuhkan untuk melarikan diri adalah:

<   to   &lt;
>   to   &gt;
&   to   &amp;
"   to   &quote;
'   to   &apos;

Standar lainnya adalah RFC 3986 "Standar URI generik", di mana URL ditangani (ini terjadi ketika browser akan mengikuti tautan karena pengguna mengklik elemen HTML).

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

Penting untuk melarikan diri dari karakter tersebut sehingga klien tahu apakah mereka mewakili data atau pembatas.

Contoh tidak terhapus:

https://example.com/?user=test&password&te&st&goto=https://google.com

Contoh, URL yang sepenuhnya sah

https://example.com/?user=test&password&te%26st&goto=https%3A%2F%2Fgoogle.com

Contoh URL sepenuhnya sah dalam nilai atribut HTML:

https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com

Skenario juga penting:

  • Javascript sebagai nilai:

    <img src="..." onclick="window.location.href = &quot;https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com&quot;;">...</a>(Ya, ;;benar.)

  • JSON sebagai nilai:

    <a href="..." data-analytics="{&quot;event&quot;: &quot;click&quot;}">...</a>

  • Hal-hal yang lolos di dalam hal-hal yang lolos, pengkodean ganda, URL di dalam URL di dalam parameter dll, ...

    http://x.com/?passwordUrl=http%3A%2F%2Fy.com%2F%3Fuser%3Dtest&amp;password=&quot;&quot;123

Daniel W.
sumber
3

Ya, Anda harus mengonversi &ke &amp;.

Alat validator html oleh W3C ini membantu untuk pertanyaan seperti ini. Ini akan memberi tahu Anda kesalahan dan peringatan untuk halaman tertentu.

Randy Greencorn
sumber
1
Saya tidak yakin bahwa validator W3C mendeteksi ini (tidak terhapus &dalam href) sebagai kesalahan.
ChrisW
6
Saat ini, validator W3C menerima unescaped & sebagai valid. Apakah ini berarti bahwa standar telah berubah dan penyandian tidak lagi diperlukan? (membuat sebagian besar jawaban di sini ketinggalan jaman)? Jika demikian, apakah ini hanya berlaku untuk href atau atribut apa pun?
matteo