Зачем использовать \ x3C вместо <при генерации HTML из JavaScript? - PullRequest
28 голосов
/ 22 ноября 2011

Я вижу, что следующий 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> внутри строки - это реальный конечный тег скрипта?Если да, то есть ли на самом деле какие-либо браузеры, которые бы не работали на этом?

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

Ответы [ 2 ]

55 голосов
/ 22 ноября 2011

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

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

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

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

<script type="text/javascript">foo(42); // call the function </script>
* * & 1 022 Ndash; что должен делать браузер в этом случае?

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

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

2 голосов
/ 22 ноября 2011

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

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

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

...