Чи кодую амперсанди в <a href…>?


157

Я пишу код, який автоматично генерує HTML, і я хочу, щоб він правильно кодував речі.

Скажіть, я створюю посилання на таку URL-адресу:

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

Я припускаю, що всі значення атрибутів повинні бути кодованими HTML. (Будь ласка, виправте мене, якщо я помиляюся.) Отже, це означає, що якщо я ввожу вищевказану URL-адресу в якірний тег, я повинен кодувати ampersand як &amp;, як це:

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

Це правильно?



6
@CiroSantilli: мова йде про фактичні рядки URL-адрес; мова йде про те, як вони кодуються, коли вони з'являються в атрибутах HTML.
JW.

Як я бачу, кодування амперсандів не завжди потрібно в html5, а відповіді застаріли.
qdinar

Відповіді:


175

Так. Суб'єкти HTML розбираються всередині атрибутів HTML, і бродячий &створив би неоднозначність. Саме тому ви завжди повинні написати &amp;замість того , щоб тільки &всередині всіх HTML - атрибутів.

Це сказало, що тільки &і цитати потрібно закодувати. Якщо у вас éв атрибуті є спеціальні символи , вам не потрібно кодувати ті, щоб задовольнити HTML-аналізатор.

Раніше було так, що URL-адреси потребували спеціального лікування з символами, що не належать до ASCII é. Вам довелося кодувати тих, хто використовує відсоткові втечі, і в цьому випадку це дасть %C3%A9, оскільки вони були визначені RFC 1738 . Однак RFC 1738 витіснили RFC 3986 (URI, Уніфіковані ідентифікатори ресурсів) та RFC 3987 (IRI, Інтернаціоналізовані ідентифікатори ресурсів), на яких WhatWG базував свою роботу, щоб визначити, як слід вести себе браузерам, коли вони бачать URL-адресу з не-ASCII символів у ньому з HTML5 . Тому тепер безпечно включати символи, що не належать до ASCII, в URL-адреси, відсотково закодовані чи ні.


1
Я був досить впевнений у цьому, але у мене був рідкісний момент сумнівів. Дякуємо за підтвердження.
JW.

1
Ви також можете кодувати пробіли як "+", а не% 20 - що полегшує читання URL-адреси.
NickG

1
+ в даний час не поважається у посиланнях mailto в рідному поштовому клієнті iPhone, для чого це варто.
Райан Олсон

1
éвсе ще потребує в кодує: stackoverflow.com/questions/2742852/unicode-characters-in-urls
lulalala

4
Я додав би (оскільки я просто потрапив у цю помилку), що якщо ви покладаєтесь на механізм шаблону, ви повинні перевірити, чи автоматично це турбує про те, щоб уникнути HTML-сутностей чи ні. У моєму випадку Twig робив це, і я неправильно двічі уникав запису &amp;в атрибут тегу, а не безпосередньо використовувати &.
Kamafeather

24

Згідно з чинними офіційними HTML-рекомендаціями, амперсанд потрібно уникати, наприклад, як &amp;у цьому контексті. Однак браузери цього не вимагають, і в HTML5 CR пропонується зробити це правилом , щоб у значеннях атрибутів застосовувалися спеціальні правила. Поточні валідатори HTML5 застаріли в цьому відношенні (див. Звіт про помилки з коментарями).

Залишатиметься можливим уникнути амперсандів у значеннях атрибутів, але окрім перевірки чинними інструментами, практичної потреби уникнути їх у hrefзначеннях немає (і невеликий ризик помилитися, якщо ви почнете уникати їх).


4
Хоча XHTML ( справжній XHTML, надісланий як application/xhtml+xml), швидше за все, завжди вимагатиме цього.
zneak

4
Одне застереження до цієї зміни, яке все ще обговорюються, обговорюється, і зрозуміле, є те , що &повинно бути добре зараз, так довго , як це « ООН неоднозначно». Один із очевидних способів зробити амперсанд неоднозначним - це слідувати за ним спочатку з непробільних символів, а потім крапкою з комою. Це амперсанд тепер неоднозначний і призведе до помилки розбору.
маті

Як сказав Юкка, безумовно, існує ризик кодування всіх амперсандів, тому подумайте, наскільки ймовірно, що один з ваших URL-адрес href містить крапку з комою. Навряд чи, оскільки я не впевнений, що коли-небудь бачив URL з крапкою з комою. Не те, щоб цього не можна було зробити. Таким чином, практично не кажучи, я не думаю, що наше використання &буде неоднозначним. Тому ми продовжуємо використовувати його некодованим у атрибутах href.
матті

Вся причина, що втеча необхідна саме через можливість неоднозначності . Ця проблема може не спричинити введення векторів атаки XSS, погану візуалізацію або будь-який вплив на 99,99% часу, але це не привід не турбувати. Правильно робити втечу важко, і завжди є можливість помилитися.
Філ

5

Я публікую нову відповідь, тому що я вважаю, що у відповіді zneak не вистачає прикладів, не показано обробку HTML та URI як різних аспектів та стандартів, а деякі незначні речі відсутні.

У вас є два стандарти щодо URL-адрес у посиланнях ( <a href).

Перший стандарт - RFC 1866 (HTML 2.0), де в розділі "3.2.1. Символи даних" ви можете прочитати символи, які потрібно уникнути, використовуючи як значення для атрибута HTML. (Атрибути самі по собі взагалі не дозволяють використовувати спеціальні символи, наприклад, <a hr&ef="http://...це не дозволено, також немає <a hr&amp;ef="http://....)

Пізніше це перейшло у стандарт HTML 4 , символи, від яких вам потрібно уникнути, є:

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

Інший стандарт - RFC 3986 "Загальний стандарт URI", де обробляються URL-адреси (це відбувається, коли браузер збирається перейти за посиланням, оскільки користувач натиснув на елемент HTML).

reserved    = gen-delims / sub-delims

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

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

Важливо уникати цих символів, щоб клієнт знав, наскільки вони представляють дані або роздільник.

Приклад без нагляду:

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

Наприклад, повністю законна URL-адреса

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

Приклад повністю законної URL-адреси у значенні атрибута HTML:

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

Також важливі сценарії:

  • Javascript як значення:

    <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>(Так, ;;правильно.)

  • JSON як значення:

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

  • Уникнуті речі всередині втечених речей, подвійне кодування, URL всередині параметра і т.д., ...

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


3

Так, ви повинні перейти &в &amp;.

Цей інструмент перевірки html від W3C корисний для таких питань. Він розповість про помилки та застереження для певної сторінки.


1
Я не впевнений, що валідатор W3C виявляє це (без сканування &в href) як помилку.
ChrisW

6
Наразі валідатор W3C приймає несказані та як дійсні. Чи означає це, що стандарт змінився і кодування більше не потрібно? (даючи більшість відповідей тут застарілими)? Якщо так, чи це стосується лише href чи будь-якого атрибута?
Маттео
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.