Мне действительно нужно кодировать '&' как '& amp;'?
Я использую&
'символ с HTML5 и UTF-8 в моем сайте <title>
, Google показывает амперсанд отлично на его выдаче, как и все браузеры в их названиях.
http://validator.w3.org/ дает мне это:
& не начал ссылаться на символ. (и, вероятно, следовало бы избежать
&
.)
Мне действительно нужно сделать &
?
Я не беспокоюсь о том, что мои страницы проверяются ради подтверждения, но мне любопытно услышать мнение людей по этому поводу, а также важно ли это и почему.
17 ответов
Да. Как и в сообщении об ошибке, в HTML атрибуты #PCDATA означают, что они анализируются. Это означает, что вы можете использовать символьные объекты в атрибутах. С помощью &
само по себе это неправильно, и если бы не снисходительные браузеры и тот факт, что это HTML, а не XHTML, нарушил бы синтаксический анализ. Просто убеги как &
и все будет хорошо.
HTML5 позволяет оставить его без экранирования, но только в том случае, если последующие данные не похожи на действительную ссылку на символ. Однако лучше просто избежать всех экземпляров этого символа, чем беспокоиться о том, какие из них должны быть, а какие нет.
Помните об этом; если вы не экранируете & в & amp;, это достаточно плохо для создаваемых вами данных (где код вполне может быть недействительным), вы также можете не экранировать теги-разделители, что является большой проблемой для данных, отправляемых пользователями, что вполне может привести к внедрению HTML и скриптов, краже файлов cookie и другим действиям.
Пожалуйста, просто избегайте вашего кода. Это избавит вас от многих неприятностей в будущем.
Помимо проверки, факт остается фактом: кодирование определенных символов важно для HTML-документа, чтобы он мог правильно и безопасно отображаться как веб-страница.
кодирование &
как &
при любых обстоятельствах, для меня это более легкое правило, благодаря которому снижается вероятность ошибок и сбоев.
Сравните следующее: что проще? что легче поднять?
Методология 1
- Напишите некоторый контент, который включает символы амперсанда.
- Кодируй их всех.
Методология 2
(с крошкой соли, пожалуйста;))
- Напишите некоторый контент, который включает символы амперсанда.
- В каждом конкретном случае посмотрите на каждый амперсанд. Определите, если:
- Он изолирован и как таковой однозначно амперсанд. например.
volt & amp
> В этом случае не беспокойтесь о его кодировании. - Он не изолирован, но вы чувствуете, что он, тем не менее, недвусмысленен, поскольку результирующая сущность не существует и никогда не будет существовать, поскольку список сущностей никогда не сможет эволюционировать. например
amp&volt
> В этом случае не беспокойтесь о его кодировании. - Он не изолирован и неоднозначен. например.
volt&
> Закодировать это.
- Он изолирован и как таковой однозначно амперсанд. например.
??
Я тщательно исследовал это и написал о своих выводах здесь: http://mathiasbynens.be/notes/ambiguous-ampersands
Я также создал онлайн-инструмент, который вы можете использовать для проверки разметки на наличие неоднозначных амперсандов или ссылок на символы, которые не заканчиваются точкой с запятой, которые недопустимы. (Ни один валидатор HTML в настоящее время не делает это правильно.)
Правила HTML5 отличаются от HTML4. Это не требуется в HTML5 - если амперсанд не выглядит так, как будто он запускает имя параметра. "©=2" по-прежнему является проблемой, например, так как & copy; является символом авторского права.
Однако мне кажется, что труднее решить, кодировать или не кодировать, в зависимости от следующего текста. Так что, возможно, самый простой путь - это все время кодировать.
Я думаю, что это превратилось в вопрос "зачем следовать спецификации, когда браузеру все равно". Вот мой обобщенный ответ:
Стандарты не являются "настоящей" вещью. Это "будущее". Если мы, как разработчики, следуем веб-стандартам, то поставщики браузеров с большей вероятностью будут правильно применять эти стандарты, и мы приблизимся к полностью совместимому вебу, где хакерские функции CSS, обнаружение функций и обнаружение браузера не нужны. Где нам не нужно выяснять, почему наши макеты ломаются в конкретном браузере, или как обойти это.
В частности, если HTML5 не требует использования & amp; в вашей конкретной ситуации, когда вы используете тип документа HTML5 (а также ожидаете, что ваши пользователи будут использовать браузеры, совместимые с HTML5), тогда нет никаких причин делать это.
Ну, если это происходит из-за пользовательского ввода, то, конечно, по очевидным причинам. Подумайте, если бы этот веб-сайт этого не делал: название этого вопроса появилось бы так, как мне действительно нужно кодировать '&' как '&'?
Если это просто что-то вроде echo '<title>Dolce & Gabbana</title>';
тогда, строго говоря, вам не нужно. Было бы лучше, но если вы этого не сделаете, пользователь не заметит разницу.
Не могли бы вы показать нам, что ваш title
на самом деле есть? Когда я отправляю
<!DOCTYPE html>
<html>
<title>Dolce & Gabbana</title>
<body>
<p>am i allowed loose & mpersands?</p>
</body>
</html>
на http://validator.w3.org/ - явно просят его использовать экспериментальный режим HTML 5 - он не имеет претензий к &
s...
Я проверял, почему URL изображения нужно экранировать, поэтому попробовал сделать это на https://validator.w3.org/. Объяснение довольно хорошее. Это подчеркивает, что даже URL должны быть экранированы. [PS: я полагаю, что он будет удален, когда его потребят, так как URL нужен &
, Кто-нибудь может уточнить?]
<img alt="" src="foo?bar=qut&qux=fop" />
Ссылка на сущность была найдена в документе, но не определена ссылка с этим именем. Часто это вызвано опечаткой имени ссылки, незакодированная амперсанды или убрав замыкающую точку с запятой (;). Наиболее распространенной причиной этой ошибки являются незашифрованные амперсанды в URL, как описано WDG в разделе "Амперсанды в URL". Ссылки на сущности начинаются с амперсанда (&) и заканчиваются точкой с запятой (;). Если вы хотите использовать буквенный амперсанд в своем документе, вы должны закодировать его как "&" (даже внутри URL!). Будьте осторожны, чтобы завершить ссылки на сущности точкой с запятой, иначе ссылка на вашу сущность может быть интерпретирована в связи со следующим текстом. Также имейте в виду, что ссылки на именованные сущности чувствительны к регистру; &Aelig; и æ разные символы. Если эта ошибка появляется в некоторой разметке, сгенерированной кодом обработки PHP-сессий, в этой статье есть объяснения и решения вашей проблемы.
В HTML &
отмечает начало ссылки, либо ссылки на символ, либо ссылки на сущность. С этого момента синтаксический анализатор ожидает либо #
обозначение ссылки на символ или имя сущности, обозначающее ссылку на сущность, за которой следует ;
, Это нормальное поведение.
Но если имя ссылки или просто ссылка открывается &
сопровождается пробелом или другими разделителями, такими как "
, '
, <
, >
, &
, Концовка ;
и даже ссылка для представления равнины &
может быть опущено:
<p title="&">foo & bar</p>
<p title="&">foo & bar</p>
<p title="&">foo & bar</p>
Только в этих случаях финал ;
или даже сама ссылка может быть опущена (по крайней мере, в HTML 4). Я думаю, что HTML 5 требует окончания ;
,
Но спецификация рекомендует всегда использовать ссылку, такую как ссылка на символ &
или ссылка на сущность &
чтобы избежать путаницы:
Авторы должны использовать
&
" (ASCII десятичное 38) вместо"&
"Во избежание путаницы с началом ссылки на символ (открытый разделитель ссылки на сущность). Авторы также должны использовать"&
msgstr "в значениях атрибутов, поскольку в значениях атрибутов CDATA допустимы ссылки на символы
Это зависит от вероятности того, что точка с запятой окажется возле вашего &
, заставляя это отображать что-то совсем другое.
Например, когда речь идет о вводе от пользователей (скажем, если вы включаете предоставленную пользователем тему сообщения на форуме в теги заголовка), вы никогда не знаете, где они могут ставить случайные точки с запятой, и это может случайно отображать странные объекты. Так что всегда убегайте в такой ситуации.
Для вашего собственного статического HTML, конечно, вы могли бы его пропустить, но включить триггеры так просто, что нет веских причин избегать этого.
Если пользователь передает его вам, или он попадет в URL, вам нужно его избежать.
Если это появляется в статическом тексте на странице? Все браузеры поймут это правильно в любом случае, вы не беспокоитесь об этом, так как он будет работать.
Да, вы должны попытаться предоставить действительный код, если это возможно.
Большинство браузеров будут молча исправлять эту ошибку, но есть проблема с обработкой ошибок в браузерах. Не существует стандарта для обработки неправильного кода, поэтому каждый поставщик браузеров должен попытаться выяснить, что делать с каждой ошибкой, и результаты могут отличаться.
Некоторые примеры, когда браузеры могут реагировать по-разному, это если вы помещаете элементы в таблицу, но вне ячеек таблицы, или если вы вкладываете ссылки друг в друга.
В вашем конкретном примере это вряд ли вызовет какие-либо проблемы, но исправление ошибок в браузере может, например, привести к тому, что браузер перейдет из режима соответствия стандартам в режим совместимости, что может привести к полной поломке макета.
Таким образом, вы должны исправить подобные ошибки в коде, если не для чего-то еще, чтобы сохранить список ошибок в валидаторе коротким, чтобы вы могли обнаружить более серьезные проблемы.
Пару лет назад мы получили сообщение о том, что одно из наших веб-приложений не отображалось корректно в Firefox. Оказалось, что страница содержала тег, который выглядел как
<div style="..." ... style="...">
Столкнувшись с повторяющимся стилевым атрибутом, IE объединяет оба стиля, в то время как Firefox использует только один из них, следовательно, различное поведение. Я изменил тег на
<div style="...; ..." ...>
и, конечно же, это решило проблему! Мораль этой истории заключается в том, что браузеры более согласованно обрабатывают действительный HTML, чем недействительный HTML. Итак, исправьте свою чертову разметку уже! (Или используйте HTML Tidy, чтобы исправить это.)
Если &
используется в HTML, то вы должны избежать его
Если &
используется в строках JavaScript, например alert('This & that');
или document.href вам не нужно использовать его.
Если вы используете document.write, то вы должны использовать его, например, document.write(<p>this & that</p>)
Если вы действительно говорите о статическом тексте
<title>Foo & Bar</title>
хранится в каком-то файле на жестком диске и обслуживается непосредственно сервером, тогда да: его, вероятно, не нужно экранировать.
Однако, поскольку в настоящее время очень мало HTML-контента, который полностью статичен, я добавлю следующий отказ от ответственности, который предполагает, что HTML-контент генерируется из какого-то другого источника (контент базы данных, пользовательский ввод, результат вызова веб-службы, результат устаревшего API)...):
Если вы не избежите простого &
то есть вероятность, что вы тоже не избежите &
или
или же <b>
или же <script src="http://attacker.com/evil.js">
или любой другой недействительный текст. Это будет означать, что вы в лучшем случае отображаете свой контент неправильно и, более вероятно, подвержены атакам XSS.
Другими словами: когда вы уже проверяете и избегаете других более проблемных случаев, тогда почти нет причин оставлять не полностью сломанный, но все же несколько подозрительный автономный и не покинутый.
Ссылка содержит довольно хороший пример того, когда и почему вам может понадобиться сбежать &
в &
https://jsfiddle.net/vh2h7usk/1/
Интересно, что мне пришлось убежать от персонажа, чтобы правильно представить его в своем ответе здесь. Если бы я использовал опцию встроенного примера кода (из панели ответов), я мог бы просто ввести &
и кажется, как и должно быть. Но если бы я вручную использовал <code></code>
элемент, то я должен уйти, чтобы представить его правильно:)
Не уверен, если это кому-нибудь пригодится... я боролся с этим некоторое время... вот замечательное регулярное выражение, которое вы можете использовать, чтобы исправить все ваши ссылки, javascript, контент. Мне пришлось иметь дело с кучей устаревшего контента, который никто не хотел исправлять.
Добавьте это к переопределению рендера на главной странице или элементе управления:
Пожалуйста, не сердитесь на меня за то, что я поставил это не в том месте:
// remove the & from href="blaw?a=b&b=c" and replace with &
//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>)", "&", RegexOptions.Singleline | RegexOptions.IgnoreCase);