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

Зачем использовать \x3C вместо <при создании HTML из JavaScript?

Я вижу, что следующий HTML-код много использовал для загрузки jQuery из сети доставки контента, но возвратился к локальной копии, если CDN недоступен (например, в Документы Modernizr):

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.1.min.js">\x3C/script>')</script>

Мой вопрос: почему последний символ < в выражении document.write() заменяется escape-последовательностью \x3C? < является безопасным символом в JavaScript и даже используется ранее в той же строке, поэтому зачем бежать туда? Разве только для предотвращения неправильной реализации браузером </script> внутри строки есть реальный тег script end? Если да, то действительно ли есть какие-то браузеры, которые не смогли бы это сделать?

В качестве последующего вопроса я также видел вариант, использующий unescape() (как указано в этом ответе) в дикой природе пару раз, Есть ли причина, почему эта версия всегда заменяет все символы < и >?

4b9b3361

Ответ 1

Когда браузер видит </script>, он считает, что это конец блока script (поскольку парсер HTML не имеет представления о JavaScript, он не может отличить что-то, что только что появляется в строке, и что фактически означало конец элемента script). Таким образом, </script> появляется буквально в JavaScript, что внутри HTML-страницы будет (в лучшем случае) причиной ошибок и (в худшем случае) быть огромной дырой в безопасности.

Вот почему вам почему-то нужно помешать появлению этой последовательности символов. Другими распространенными обходными решениями для этой проблемы являются "<"+"/script>" и "<\/script>" (все они сводятся к одному и тому же).

В то время как некоторые считают, что это "ошибка", на самом деле это должно произойти именно так, поскольку, согласно спецификации , часть HTML пользовательского агента полностью отделен от скриптового движка. Вы можете поместить всевозможные вещи в теги <script>, а не только на JavaScript. W3C упоминает VBScript и TCL в качестве примеров. Другим примером является плагин шаблона jQuery, который также использует эти теги.

Но даже в JavaScript, где вы могли бы предположить, что такое содержимое в строках может быть распознано и, следовательно, не должно рассматриваться как конечные теги, следующая неоднозначность возникает, когда вы рассматриваете комментарии:

<script type="text/javascript">foo(42); // call the function </script>

– что должен сделать браузер в этом случае?

И, наконец, что относительно браузеров, которые даже не знают JavaScript? Они просто проигнорировали бы часть между <script> и </script>, но если бы вы дали разную семантику последовательности символов </script> на основе знаний браузеров JavaScript, у вас внезапно возникли бы два разных результата на этапе синтаксического анализа HTML.

Наконец, в отношении вашего вопроса о замене всех угловых скобок: я бы сказал, по крайней мере, в 99% случаев, что для обфускации, т.е. чтобы скрыть (от антивирусного программного обеспечения, цензуры прокси (например, в вашем примере (вложенные parens awesome)) и т.д.) тот факт, что ваш JavaScript делает некоторые вещи HTML-y. Я не могу думать о хороших технических причинах, чтобы скрыть что-либо, кроме </script>, по крайней мере, не для разумно современных браузеров (и тем самым я имею в виду почти что-то новое, чем Мозаика).

Ответ 2

Некоторые парсеры обрабатывают версию < в качестве закрывающего тега и интерпретируют код как

<script>
  window.jQuery || document.write('<script src="js/libs/jquery-1.6.1.min.js">
</script>

\x3C является шестнадцатеричным для <. Они взаимозаменяемы в пределах script.