</script>
должен быть разбит, потому что в противном случае это приведет к <script></script>
преждевременному завершению блока. На самом деле он должен быть разделен между <
и /
, потому что предполагается, что блок скрипта (согласно SGML) завершается любой последовательностью открытия конечного тега (ETAGO) (то есть </
) :
Хотя элементы STYLE и SCRIPT используют CDATA для своей модели данных, для этих элементов пользовательские агенты должны обрабатывать CDATA по-разному. Разметка и сущности должны обрабатываться как необработанный текст и передаваться приложению как есть. Первое вхождение последовательности символов " </
" (открытый разделитель конечных тегов) обрабатывается как завершение конца содержимого элемента. В допустимых документах это будет конечный тег для элемента.
Однако на практике браузеры заканчивают парсинг блока сценариев CDATA только фактическим </script>
тегом close.
В XHTML такой специальной обработки для блоков скриптов нет, поэтому любой <
(или &
) символ внутри них должен быть таким же, &escaped;
как и в любом другом элементе. Однако тогда запутанные браузеры, анализирующие XHTML как устаревший HTML. Существуют обходные пути, связанные с блоками CDATA, но проще всего избежать использования этих символов без экранирования. Лучший способ написания элемента script из скрипта, который работает с любым типом парсера:
<script type="text/javascript">
document.write('\x3Cscript type="text/javascript" src="foo.js">\x3C/script>');
</script>
\/
является допустимой escape-последовательностью/
, так почему бы не использовать ее вместо этих строковых литералов<
? Напримерdocument.write('<script src=foo.js><\/script>');
. Кроме того,</script>
это не единственная последовательность символов, которая может закрыть<script>
элемент. Немного больше информации здесь: mathiasbynens.be/notes/etago<\/script>
хорошо в этом случае, но он будет работать только в HTML; в XHTML без дополнительной обертки разделов CDATA это все еще ошибка правильной формы. Кроме того, вы можете использовать\x3C
встроенные атрибуты обработчика событий,<
которые также будут недопустимыми как в HTML, так и в XHTML, поэтому он имеет более широкую применимость: если бы я выбирал один, легко автоматизируемый способ экранирования чувствительных символов в строковых литералах JS для всех контекстов, это тот, за которым я бы пошел.<
могут использоваться встроенные атрибуты обработчика событий. html5.validator.nu/… И вы правы насчет совместимости XHTML\x3C
для sich, но поскольку XHTML не поддерживаетdocument.write
(илиinnerHTML
) в любом случае, я не понимаю, насколько это актуально.document.write
- не имеет значения, это просто пример. ОП мог бы использовать innerHTML, он о том, чтобы скрыть</
последовательность символов от анализатора разметки, где бы он ни происходил. Просто большинство синтаксических анализаторов допускают это внутри элемента скрипта, когда строго не должны (но анализаторы HTML очень терпимы). Вы правы, хотя этого<\/
достаточно во всех случаях для HTML.document.write('<script src="foo.js">\x3C/script>')
кажется достаточным во всех браузерах до IE6. (Я пропустил атрибут type, потому что он не требуется в HTML5, и при этом он не применяется в соответствии с требованиями любого браузера.)Вот еще один вариант, который я использовал, когда хотел сгенерировать встроенный тег script (чтобы он выполнялся немедленно) без необходимости экранирования:
(Примечание: вопреки большинству примеров в сети, я не устанавливаю
type="text/javascript"
ни теги включения, ни сгенерированный тег: нет браузера, не имеющего этого по умолчанию, и поэтому он является избыточным, но также не повредит, если вы не согласны).источник
Я думаю, что для предотвращения того, чтобы синтаксический анализатор HTML браузера интерпретировал <script>, и главным образом </ script>, как закрывающий тег реального скрипта, однако я не думаю, что использование document.write является отличной идеей для оценки скрипта блоки, почему бы не использовать DOM ...
источник
Решение, опубликованное Bobince, отлично подходит для меня. Я хотел предложить альтернативный метод для будущих посетителей:
В этом примере я включил условную загрузку для jQuery, чтобы продемонстрировать вариант использования. Надеюсь, это кому-нибудь пригодится!
источник
</script>
Внутри строки litteral Javascript интерпретируется HTML парсер в качестве закрывающего тега, вызывая неожиданное поведение ( см пример на JSFiddle ).Чтобы избежать этого, вы можете размещать свой javascript между комментариями (этот стиль кодирования был обычной практикой, когда Javascript плохо поддерживался браузерами). Это будет работать ( см. Пример в JSFiddle ):
... но, если честно, использование
document.write
- это не то, что я бы посчитал лучшей практикой. Почему бы не манипулировать DOM напрямую?источник
append
вместоappendChild
. Исправил ответ. Спасибо, что заметили!