Подтвердить что ты не робот

Почему "& reg" отображается как "®" без ограничивающей точки с запятой

У меня возникла проблема, которая была выявлена ​​в нашей маркетинговой кампании, основанной на Google adwords. Одним из стандартных используемых параметров является "регион". Когда пользователь выполняет поиск и нажимает на спонсируемую ссылку, Google генерирует длинный URL-адрес для отслеживания щелчка и отправляет кучу материала в реферере. Мы фиксируем это для наших записей, и мы заметили, что параметр "Регион" происходит неправильно. Что должно быть

http://ravercats.com/meow?foo=bar&region=catnip

вместо этого появляется как:

http://ravercats.com/meow?foo=bar®ion=catnip

Я проверил, что это происходит во всех браузерах. Я понимаю, что синтаксис HTML-объекта определяется следующим образом:

&VALUE;

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

Кто-нибудь знает, почему это происходит? Это ошибка в DTD? (Я ищу текущий HTML DTD, чтобы узнать, могу ли я это понять). Я пытаюсь выяснить, что будет распространено в браузерах, чтобы это произошло, поэтому я ищу DTD.

Вот доказательство, которое вы можете использовать. Возьмите этот код, внесите из него HTML файл и отрисуйте его в браузере:

<html>
<a href="#" onclick="location.href='http://foo.com/bar?foo=bar&region=US&register=lowpass&reg_test=fail&trademark=correct'; return false;">http://foo.com/bar?foo=bar&region=US&register=lowpass&reg_test=fail&trademark=correct</a>
</html>

РЕДАКТИРОВАТЬ: всем, кто предполагает, что мне нужно избежать всего URL-адреса, приведенные выше примерные URL-адреса являются именно такими примерами. Настоящий URL-адрес поступает напрямую от Google, и я не могу контролировать, как он построен. Эти предложения, хотя и действительны, не отвечают на вопрос: "Почему это происходит".

4b9b3361

Ответ 1

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

Либо вы знаете, что такое весь список, либо вы следуете правилам HTML5, если & действителен без экранирования (e, g, за которым следует пробел) или иначе всегда выходите & как &amp; когда есть сомнения.

Для справки, полный список названных имен символов, которые распознаются без точки с запятой:

AElig, AMP, Aacute, Acirc, Agrave, Aring, Atilde, Auml, COPY, Ccedil, ETH, Eacute, Ecirc, Egrave, Euml, GT, Iacute, Icirc, Igrave, Iuml, LT, Ntilde, Oacute, Ocirc, Ograve, Oslash, Otilde, Ouml, QUOT, REG, THORN, Uacute, Ucirc, Ugrave, Uuml, Yacute, aacute, acirc, sharp, aelig, agrave, amp, aring, atilde, auml, brvbar, ccedil, cedil, cent, копия, curren, deg, divide, eacute, ecirc, egrave, eth, euml, frac12, frac14, frac34, gt, iacute, icirc, iexcl, igrave, iquest, iuml, laquo, lt, macr, micro, middot, nbsp, не, ntilde, oacute, ocirc, ograve, ordf, ordm, oslash, otilde, ouml, para, plusmn, pound, quotquo, raquo, reg, sect, shy, sup1, sup2, sup3, szlig, thorn, times, uacute, ucirc, ugrave, uml, uuml, yacute, yen, yuml

Однако следует отметить, что только в том случае, когда в значении атрибута, ссылки на именованные символы в приведенном выше списке не обрабатываются как таковые, согласовывая синтаксические анализаторы HTML5, если следующий символ является = или буквенно-цифровым символом ASCII.

Для полного списка имен символов с или без конечных точек с запятой, см. здесь

Ответ 2

Это очень грязный бизнес и зависит от контекста (текстовый контент и значение атрибута).

Формально, по спецификациям HTML вплоть до HTML 4.01, ссылка на сущность может появляться без конечной точки с запятой, если следующий символ не является символом имени. Так, например, &region= будет синтаксически корректным, но undefined, поскольку объект region не определен. XHTML делает конечную точку с запятой.

Браузеры традиционно играют другие правила. Из-за общего синтаксиса URL-адресов запросов они анализируют, например. href="http://ravercats.com/meow?foo=bar&region=catnip", так что &region не рассматривается как ссылка на сущность, а как только текстовые данные. И авторы в основном использовали такие конструкции, хотя они формально неверны.

Вопреки тому, что, кажется, говорит вопрос, href="http://ravercats.com/meow?foo=bar&region=catnip" действительно работает хорошо. Проблемы возникают, когда строка не находится в значении атрибута, а внутри текстового содержимого, что довольно необычно: мы обычно не пишем URL-адреса в тексте. В тексте &region= обрабатывается так, что &reg распознается как ссылка на сущность (для "®" ), а остальные - только символьные данные. Такое нечетное поведение становится официальным в HTML5 CR, где предложение 8.2.4.69 Обозначение символьных символов описывает "двойной стандарт":

Если ссылка символа потребляется как часть атрибута, и последний совпадающий символ не является ";" (U + 003B) и следующий символ является либо символом "=" (U + 003D), либо в диапазоне ASCII цифры, прописные буквы ASCII или строчные буквы ASCII, то по историческим причинам все символы, которые были сопоставлены после того, как символ U + 0026 AMPERSAND (&) должен быть не загружен, и ничего не возвращается.

Таким образом, в значении атрибута даже &reg= не будет рассматриваться как содержащий ссылку на символ, и еще меньше &region=. (Но reg_test= - это другой случай из-за символа подчеркивания.)

В текстовом контенте применяются другие правила. Конструкция &region= вызывает тогда ошибку синтаксического анализа (по правилам HTML5 CR), но с четко определенной обработкой ошибок: &reg распознается как ссылка на символ.

Ответ 3

Возможно, попробуйте заменить & как &amp;? Амперсанды - это символы, которые также должны быть экранированы в HTML, потому что они зарезервированы для использования в качестве частей сущностей.

Ответ 4

1: Следующая разметка недействительна в первую очередь (используйте службу проверки валидности W3C)

<a href="http://foo.com/bar?foo=bar&region=US&register=lowpass&reg_test=fail&trademark=correct"></a>

В приведенном выше примере символ & должен быть закодирован как &amp;, например:

<a href="http://foo.com/bar?foo=bar&amp;region=US&amp;register=lowpass&amp;reg_test=fail&amp;trademark=correct"></a>

2: Браузеры терпимы; они пытаются разобраться в сломанном HTML. В вашем случае все возможные допустимые объекты HTML преобразуются в объекты HTML.

Ответ 5

Устраните выход!

Достаточно просто вам нужно закодировать формат url в html-формате для точного представления (в идеале вы бы сделали это с помощью функции escaping переменной шаблона шаблона, но запретили это с помощью htmlspecialchars($url) или htmlentities($url) в php).

Посмотрите на свой тестовый пример, а затем правильно закодированный html на этом jsfiddle: http://jsfiddle.net/tchalvakspam/Fp3W6/

Неактивный код здесь:

<div>
Unescaped:
<br>
<a href="">http://foo.com/bar?foo=bar&region=US&register=lowpass&reg_test=fail&trademark=correct</a>
</div>

<div>
Correctly escaped:
<br>
http://foo.com/bar?foo=bar&amp;region=US&amp;register=lowpass&amp;reg_test=fail&amp;trademark=correct
</div>

Ответ 6

Мне кажется, что то, что вы получили от google, не является фактическим URL, а переменной, которая ссылается на url (строка запроса). Итак, вот почему он анализируется как отметка регистрации при визуализации.

Я бы сказал, вы должны его кодировать и декодировать при обработке. Как и любая другая переменная, содержащая специальные сущности.

Ответ 7

Чтобы этого не произошло, вы должны закодировать URL-адреса, который заменяет символы, такие как амперсанд, на% и шестнадцатеричное число за ним в URL-адресе.