Ответ 1
Это поднимает важный момент, когда текст внутри тегов <script>
на HTML-странице анализируется парсером HTML до его анализа парсером Javascript.
Этот код недействителен синтаксисом HTML5, поэтому в спецификации HTML5 нет ничего, что могло бы дать нам представление о том, что здесь происходит. Чтобы быть конкретным, есть две проблемы:
- Существует тег
<script>
без закрытия</script>
. - Открывается
<!--
без закрытия-->
. (см. ограничения для содержимого элементов script)
Обе эти проблемы помещают браузер HTML-браузера в режим разбора ошибок, а это значит, что они пытаются понять недопустимый синтаксис. То, что браузеры будут делать, пытаясь понять недопустимый синтаксис, - это поведение undefined, что технически означает, что что-то может случиться (например, носовые демоны), По сути дела, де-факто поведение браузеров согласуется с тем, как они справляются с этим поведением undefined, но тем не менее оно undefined.
По какой-то причине эта комбинация проблем синтаксиса рядом друг с другом заставляет браузеры игнорировать текст позже в документе.
EDIT: Я определил, как возникает ошибка синтаксического анализа, перейдя через эту часть спецификации HTML5.
Текстовое содержимое script (исключая пробелы)
var a = '<!--<script>';
Это должно соответствовать следующему правилу грамматики:
data1 *( escape [ script-start data3 ] "-->" data1 ) [ escape ]
Мы можем начать синтаксический анализ текстового содержимого, сопоставляя data1
, который имеет следующее правило:
data1 = < any string that doesn't contain a substring that matches not-data1 >
not-data1 = "<!--"
То есть строка var a = '
совпадает с производством data1
. Он заканчивается там, потому что следующая часть <!--
.
Для последующего текста в script он должен соответствовать произведению escape
, которое выглядит следующим образом:
escape = "<!--" data2 *( script-start data3 script-end data2 )
Соответствует следующей части текста. До сих пор мы
data1 var a = '
escape <!--
data2 ???
Теперь ничто не может содержаться в data2
, потому что data2
production запрещает подстроку <script>
(т.е. a script-start
)!
data2 = < any string that doesn't contain a substring that matches not-data2 >
not-data2 = script-start / "-->"
Лексер не может выполнять действительные шаги в соответствии с грамматикой, поэтому браузер теперь должен перейти в обработку ошибок.