Кодировать ли амперсанды в <a href...>?

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

Скажем, я генерирую ссылку на следующий URL:

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

Я предполагаю, что все значения атрибутов должны быть в кодировке HTML. (Пожалуйста, исправьте меня, если я ошибаюсь.) Это означает, что если я помещаю вышеуказанный URL в тег привязки, я должен закодировать амперсанд как &amp;, как это:

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

Это верно?

4 ответа

Решение

Да, это. 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, в процентах или нет.

Согласно действующим официальным рекомендациям HTML, амперсанд должен быть экранирован, например, как &amp; в таких ситуациях Тем не менее, браузеры не требуют этого, и HTML5 CR предлагает сделать это правилом, чтобы специальные значения применялись в значениях атрибутов. Текущие валидаторы HTML5 в этом отношении устарели (см. Сообщение об ошибке с комментариями).

По-прежнему будет возможно избежать амперсандов в значениях атрибутов, но кроме проверки с помощью текущих инструментов, нет практической необходимости избегать их в href ценности (и есть небольшой риск ошибиться, если вы начнете избегать их).

Я публикую новый ответ, потому что обнаружил, что в ответе 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  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

Важно избегать этих символов, чтобы клиент знал, представляют ли они данные или разделитель.

Пример unescaped:

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 внутри URL внутри параметра и т. Д.,...

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

Да, вы должны конвертировать & в &amp;,

Этот инструмент проверки html от W3C полезен для вопросов, подобных этому. Он расскажет вам об ошибках и предупреждениях для конкретной страницы.

Да, это правильно.

Другие вопросы по тегам