Мені дійсно потрібно кодувати "&" як "& amp;"


207

Я використовую &символ " " з HTML5 та UTF-8 у своїх сайтах <title>. Google показує розмір амперсанда та штраф на своїх SERP, як і всі браузери в їх назвах.

http://validator.w3.org дає мені це:

& не запустив посилання на персонаж. (І, мабуть, слід було б уникнути як &amp;.)

Мені справді потрібно робити &amp;?

Мене не метушить, що мої сторінки перевіряються заради перевірки, але мені цікаво почути думку людей щодо цього, і якщо це важливо і чому.


63
Технічні характеристики цього не кажуть. Плакат посилається на HTML5, який не вимагає виходу з амперсанда у всіх сценаріях.
Меттью Вілсон

2
Це має бути Wiki Wiki, оскільки ви шукаєте думки, і якщо ви не метушитеся щодо перевірки, це означає, що немає об'єктивної основи, на якій можна відповісти.
Річард JP Le Guen

6
@Richard: справді? Хоча я не згоден з тим, що "перевірка не має значення", я вважаю це дуже об'єктивним питанням: "це порушує щось інше, ніж специфікацію?"
Йоахім Зауер

2
@YiJiang Поточні веб-браузери дуже добре розуміють користувача . Так само і Google . Це частина Spec. Майбутні веб-браузери можуть не прощати. Тому завжди корисно перевірити, як це робить Вікіпедія, і скопіювати їх.
unixman83

2
Специфікація HTML говорить прийняти введення лайна. Це означає, що ваш сайт зараз "дозволений" для лайна? Закрийте теги, які потрібно закрити і уникати речей! Заходьте люди.
doug65536

Відповіді:


143

Так. Так само, як сказано в помилці, атрибути в HTML - це #PCDATA, тобто вони розібрані. Це означає, що ви можете використовувати атрибути символів у атрибутах. Використання &саме по собі неправильно, і якщо не поблажливіші браузери, а той факт, що це HTML, а не XHTML, порушив би синтаксичний аналіз. Просто уникнути цього як &amp;і все було б добре.

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

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

Будь ласка, уникайте свого коду. Це вбереже вам багато клопоту в майбутньому.


9
Жоден веб-переглядач ніколи не «неправильно» інтерпретує «a» сам по собі. Кожен існуючий браузер відображає його як "&". Вважаючи, що він прямо просив практичних причин зробити це, і що він заявив, що йому не байдуже валідація ..
Томас Боніні

47
Так. Але морально, чи варто покладатися на поблажливість та "приємне" поводження з помилками браузерів? Або ми повинні просто написати правильний код?
Делан Азабані

8
@ Делан: хоча я намагаюся зробити кожну сторінку, яку я пишу валідантною, я розумію, читаючи його питання, що він не хвилює "морально". Він просто переймається, працює він чи ні. Це дві різні філософії і в обох є свої плюси і мінуси, і немає "правильної". Наприклад, цей веб-сайт не підтверджує, але все ж це чудовий веб-сайт.
Томас Боніні

3
@Andreas, але у браузерів достатньо помилок у тому, як вони інтерпретують правильний код, залежно від того, коли вони отримують правильні результати, коли ви надсилаєте їм безглузду розмітку - це химерність. Сьогодні він може працювати з цим прикладом, а потім провалитись із наступним прикладом (скажімо, якщо наступний приклад має напівкрапку десь після &)
Джон Ханна

11
Здається, всі говорять про HTML5, але в первинному питанні зазначено, що HTML5 використовується. HTML5 явно дозволяє без націлення та в цій ситуації, якщо тільки наступне & зазвичай не розшириться на сутність (наприклад, & copy = 2 є проблематичним, але & x = 2 нормально).
Меттью Вілсон

55

Проверка вбік, залишається фактом, що кодування певних символів є важливим для документа HTML, щоб він міг правильно та безпечно відображатись як веб-сторінка.

Кодування, &як &amp;за будь-яких обставин, для мене - це простіше правило, яким можна жити, зменшуючи ймовірність помилок і збоїв.

Порівняйте наступне: що простіше? що простіше підробити ?

Методика 1

  1. Напишіть деякий вміст, який включає символи "амперсанд".
  2. Зашифруйте їх усі.

Методика 2

(з зерном солі, будь ласка;))

  1. Напишіть деякий вміст, який включає символи "амперсанд".
  2. Проаналізуйте кожен окремий випадок. Визначте, чи:
    • Він ізольований і як такий однозначно амперсанд. напр. volt & amp
       > У такому випадку не переймайтеся кодуванням.
    • Він не є ізольованим, але ви вважаєте, що це, однак, однозначно, оскільки отримана сутність не існує і ніколи не існуватиме, оскільки список організацій ніколи не міг би розвиватися. напр. amp&volt
       > У цьому випадку не переймайтеся кодуванням.
    • Це не ізольовано, а неоднозначно. напр. volt&amp
       > Кодуйте його.

??


3
Другий випадок amp&volt є неоднозначним: Є чи &voltтепер посилання на сутність чи ні?
Gumbo

6
@Gumbo Амперсанд в amp&voltце НЕ неоднозначний амперсанд (відповідно до визначення в HTML - специфікації). Див. Mathiasbynens.be/notes/ambiguous-ampersands та mothereff.in/ampersands#amp%26volt .
Mathias Bynens

@MathiasBynens На сьогодні (2019 р.) Визначення неоднозначного амперсанда мало змінилося від визначення, яке ви цитували ще в 2011 році в mathiasbynens.be/notes/ambiguous-ampersands .
Якоб К. каже, що

21

Правила HTML5 відрізняються від HTML4. Це не потрібно в HTML5 - якщо амперсанд не схожий на те, що він починає назву параметра. Наприклад, "& copy = 2" залишається проблемою, наприклад, оскільки & copy; є символом авторського права.

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


2
Це як цитування значень атрибутів - не потрібно, але ви не можете помилитися, якщо будете робити це постійно.
Пол Д. Уейт

3
&copy=2це не така велика проблема, як ви можете подумати. У значеннях атрибутів (наприклад, hrefатрибут) значення &copyне вважатиметься посиланням на символи ©. Поза значенням атрибута.
Mathias Bynens

З огляду на те, що амперсанд зазвичай передує і пробіл в англійському тексті, не важко запам’ятати або подумати про правило, яке я дотримуюся: Якщо амперсанд не торкається іншого видимого символу, який майже завжди є, він не потребує кодування. В іншому випадку просто кодуйте заради простоти.
Карл Сміт

Чи можете ви додати посилання на правила HTML5?
Феррібіг

17

Я думаю, що це перетворилося на більше питання про те, "чому дотримуватися специфікації, коли браузер не хвилює". Ось моя узагальнена відповідь:

Стандарти - це не «присутні» речі. Вони - річ "майбутнього". Якщо ми, як розробники, дотримуємося веб-стандартів, то, швидше за все, постачальники браузерів правильно застосовують ці стандарти, і ми переходимо ближче до цілком сумісної мережі, де CSS-хаки, виявлення функцій та виявлення браузера не потрібні. Там, де нам не потрібно розбиратись, чому наші макети розбиваються на конкретний веб-переглядач, або як їх обійти.

Зокрема, якщо HTML5 не вимагає використання & amp; у вашій конкретній ситуації, і ви використовуєте doctype HTML5 (а також очікуєте, що ваші користувачі використовуватимуть браузери, сумісні з HTML5), то немає підстав для цього.


1
Зважаючи на це, загалом кажучи, ви повинні пам’ятати, що більшість «стандартних» способів все ще знаходяться в режимі чернетки і можуть змінитися в майбутньому.
refaelio

6

Ну, якщо це з введення користувача, то абсолютно так, з очевидних причин. Подумайте, якщо цей веб-сайт цього не зробив: назва цього питання відобразиться, як мені справді потрібно кодувати "&" як "&"?

Якщо це просто щось на кшталт, echo '<title>Dolce & Gabbana</title>';то строго кажучи, не потрібно. Було б краще, але якщо ви цього не зробите, користувач не помітить різниці.


5

Не могли б ви показати нам, що 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 ...


1
Так, HTML5 має інший синтаксичний аналізатор, ніж попередні парсери HTML та XHTML, і дозволяє в певних ситуаціях розгортати нерозширені амперсанди.
kevinji

Що стосується цих прикладів, у HTML5 це нічого нового. І те, <title>Dolce & Gabbana</title>і інше, <p>Dolce & Gabbana</p>є дійсним HTML 2.0.
Матіас Байненс

4

У HTML &позначає початок посилання, або посилання символів, або посилання на сутність . З цього моменту на аналізатор очікує або #позначення посилання символу, або ім'я сутності, що позначає посилання на сутність, за яким слідує a ;. Це нормальна поведінка.

Але якщо ім'я посилання або просто посилання відкриття &супроводжується пропуском або іншими роздільниками подобається ", ', <, >, &, закінчення ;і навіть посилання для подання рівнини &можна опустити:

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

Тільки в цих випадках закінчення ;або навіть сама посилання можуть бути опущені (принаймні, в HTML 4). Я думаю, що HTML 5 вимагає закінчення ;.

Але специфікація рекомендує завжди використовувати такі посилання, як посилання символів &#38;або посилання на сутність, &amp;щоб уникнути плутанини:

Автори повинні використовувати " &amp;" (ASCII десятковий 38) замість " &", щоб уникнути плутанини з початком посилання символів (відкритий роздільник обмеження сутності). Автори також повинні використовувати " &amp;" значення значень атрибутів, оскільки посилання символів дозволені в значеннях атрибутів CDATA.


1
Це специфікація HTML 4, на яку ви посилаєтесь; з мого читання (проекту) специфікації HTML 5, заборонені лише неоднозначні амперсанти. Амперсанд, за яким, наприклад, пробіл, не є неоднозначним, і тому (знову ж таки моїм читанням) слід дозволити - дивіться мою відповідь для розмітки, яку приймає валідатор HTML 5.
AakashM

1
@AakashM: Я не впевнений, це звучало так.
Gumbo

3

Якщо користувач передасть його вам, або він з’явиться в URL-адресі, вам потрібно уникнути цього.

Якщо він відображається в статичному тексті на сторінці? Усі браузери отримають це право в будь-якому випадку, ви не дуже турбуєтесь про це, оскільки він буде працювати.


3

Оновлення (березень 2020 р.): Валідатор W3C більше не скаржиться на уникнення URL-адрес.

Я перевіряв, чому потрібно уникати URL-адреси зображення, тому спробував це в https://validator.w3.org . Пояснення досить приємне. Це підкреслює, що навіть URL-адреси потрібно уникати. [PS: Я вважаю, що він не зміниться, коли його буде використано з моменту потреби URL-адреси &. Хтось може уточнити?]

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

У документі знайдено посилання на суб’єкт господарювання, але посилання на цю назву не визначено. Часто це спричинено неправильним написанням опорного імені, некодованими амперсандами або відхиленням крапки з комою (;). Найпоширенішою причиною цієї помилки є некодовані розширення в URL-адресах, як описано WDG у розділі "Амперсанд в URL-адресах". Посилання на об'єкти починаються з символу "" (")" і & закінчуються крапкою з комою (;). Якщо ви хочете використовувати в своєму документі буквальну амперсанд, ви повинні кодувати це як "&" (навіть усередині URL-адрес!). Будьте обережні, щоб закінчити посилання юридичних осіб крапкою з комою або посилання вашої сутності може бути інтерпретоване у зв'язку з наступним текстом. Також майте на увазі, що названі посилання суб’єктів залежать від регістру; & Aelig; і æ - різні символи.


1
Прочитайте найкращу відповідь. Атрибути #PCDATA і тому аналізуються. Суб'єкти обробляються там. У вашому прикладі &починається посилання на сутність. Після читання &quxаналізатор не знаходить остаточної крапки з комою ( ;), але стикається зі знаком рівності ( =), який не може бути частиною назви сутності. Це має бути помилка розбору, якщо аналізатор намагався бути дійсно суворим (згідно HTML 4). У HTML 5 розбір об'єктів в цілому більш спокійний.
Palec

1
Я підозрюю, що в цілому найкраще з ;цієї причини використовувати як роздільник у рядках запитів (коли ви керуєте посиланням).
Демі

2

Так, ви можете спробувати подати дійсний код, якщо це можливо.

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

Деякі приклади, коли веб-переглядачі, ймовірно, реагують по-різному - це якщо ви помістите елементи всередину таблиці, але поза клітинками таблиці, або якщо ви вкладете посилання всередині одного.

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

Отже, вам слід виправити подібні помилки в коді, якщо не що-небудь інше, щоб не було списку помилок у валідаторі коротким, щоб ви могли помітити більш серйозні проблеми.


2

Пару років тому ми отримали звіт про те, що один із наших веб-додатків не відображався належним чином у Firefox. Виявилося, що на сторінці містився тег, який виглядав так

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

Зустрічаючись з повторним атрибутом стилю, IE поєднує обидва стилі, тоді як Firefox використовує лише один з них, отже, і різну поведінку. Я змінив тег на

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

і, звичайно, досить, вона виправила проблему! Мораль історії полягає в тому, що браузери мають більш послідовну обробку дійсного HTML, ніж недійсного HTML. Отже, виправте вже свою прокляту розмітку! (Або використовуйте HTML Tidy, щоб виправити це.)


1

якщо &він використовується в HTML, то вам слід уникати цього

Якщо &використовується в рядках javascript, наприклад, alert('This & that');або document.href, вам не потрібно використовувати його.

Якщо ви використовуєте document.write, тоді ви повинні використовувати його, наприклад document.write(<p>this &amp; that</p>)


document.writeслід уникати. Дивіться поле попередження в w3.org/html/wg/drafts/html/master/dom.html#document.write%28%29
Oriol

Хороший момент о document.write(). Але суперечливо Алекс замислюється над написанням документа із скриптів, imo. +1
Патрік М

1

Це залежить від ймовірності того, що крапка з комою закінчиться біля вашого &, що призведе до того, що він відображатиме щось зовсім інше.

Наприклад, працюючи з інформацією від користувачів (скажімо, якщо ви включите в теги заголовка надану користувачем тему повідомлення на форумі), ви ніколи не знаєте, де вони можуть розміщувати випадкові крапки з комою, і це може випадково відображати дивні сутності. Тому завжди біжіть у цій ситуації.

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


0

Якщо ви справді говорите про статичний текст

<title>Foo & Bar</title>

зберігається в якомусь файлі на жорсткому диску і подається безпосередньо сервером, тоді так: його, ймовірно, не потрібно уникати.

Однак, оскільки на сьогоднішній день дуже мало вмісту HTML, що є повністю статичним, я додам наступну відмову, яка передбачає, що вміст HTML генерується з якогось іншого джерела (вміст бази даних, введення користувача, результат виклику веб-служби, результат застарілого API,. ..):

Якщо ви не уникнути простий &, то швидше за все , ви також не уникнути &amp;або &nbsp;або <b>або <script src="http://attacker.com/evil.js">будь-якої іншої невірний текст. Це означає, що ви в кращому випадку показуєте вміст неправильно і, швидше за все, піддаєтеся нападу XSS .

Іншими словами: коли ви вже перевіряєте та ухиляєтесь від інших більш проблемних випадків, то майже немає причин залишати не зовсім розбитий, але все ще дещо рибний автономний - і без нагляду.


2
Я не спровокував, але, якщо мені доведеться здогадуватися, я б сказав, що вас прихильнили, тому що ваша відповідь (хоча розумна) є дещо невідповідністю питання. Він не питає про уникнення введення користувачем. Він має контроль над персонажами і в основному запитує "Якщо це робить те, що я хочу, чи дійсно важливо дотримуватися мовної специфікації до букви?" Тобто він знає, що є & тому, що він його вклав.
Метт

@Matt: Я бачу, і це було б розумно. Я просто припускав, що ніхто більше не пише повністю статичних HTML-сторінок і майже весь вміст є хоча б дещо динамічним (зазвичай на основі деякого вмісту бази даних). Можливо, це припущення повинно було бути явним.
Йоахім Зауер

-1

не впевнений, чи корисно це кому-небудь ... Я боровся з цим деякий час ... ось славний вираз, який ви можете використати, щоб виправити всі ваші посилання, JavaScript, вміст. Мені довелося зіткнутися з тоною застарілого вмісту, який ніхто не хотів виправити.

Додайте це до перегляду Render на своїй головній сторінці або елементі управління:

Будь ласка, не спалахуйте мене за те, що поставити це в неправильному місці:

// 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);

-1

Посилання має досить хороший приклад того , коли і чому ви , можливо , доведеться піти &в&amp;

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

Цікаво, що мені довелося уникнути персонажа, щоб правильно його зобразити у своїй відповіді. Якби я використовував вбудований параметр зразка коду (на панелі відповідей), я можу просто ввести &amp;і він виглядає як слід. Але якби я вручну використовував <code></code>елемент, то мені доведеться бігти, щоб правильно його представити :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.