为什么<! - <script>会导致浏览器中的DOM树中断?

Gea*_*Lin 21 html javascript dom

当我看到解决http://escape.alf.nu第15级的答案时,我注意到这<!--<script>将导致DOM解析器中断.在以下HTML中,您将看不到字符串"Test"(在IE 11和Firefox&Chrome上测试):

<!DOCTYPE HTML>
<html>
    <body>
        <script>
            var a = '<!--<script>';
        </script>
        <p>Test</p>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

上面HTML的DOM树

但是这两个脚本将显示"Test":

<!DOCTYPE HTML>
<html>
    <body>
        <script>
            var a = '<!--';
        </script>
        <p>Test</p>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

和,

<!DOCTYPE HTML>
<html>
    <body>
        <script>
            var a = '<script>';
        </script>
        <p>Test</p>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

我不明白,为什么会这样?

Pet*_*son 23

这提出了重要的一点,<script>HTML页面上的标签内部的文本在由Javascript解析器解析之前由HTML解析器解析.

此代码不是有效的HTML5语法,因此HTML5规范中没有任何内容可以为我们提供有关此处的内容的线索.具体而言,有两个问题:

这两个问题都会使浏览器的HTML解析器进入错误解析模式,这意味着他们试图理解无效语法.当尝试理解无效语法时,浏览器将会做什么是未定义的行为,这在技术上意味着任何事情都可能发生(例如鼻子恶魔).该事实上这里的行为似乎是浏览器上如何处理这个不确定的行为同意,但它是不确定的行为仍然.

无论出于何种原因,这种语法问题的组合彼此相邻会导致浏览器忽略文档中的文本.


编辑:我已经确定了如何通过单步执行HTML5规范的这一部分来产生解析错误.

脚本的文本内容(不包括空格)是

var a = '<!--<script>';
Run Code Online (Sandbox Code Playgroud)

这必须符合以下语法规则:

data1 *( escape [ script-start data3 ] "-->" data1 ) [ escape ]
Run Code Online (Sandbox Code Playgroud)

我们可以通过匹配开始解析文本内容data1,其具有以下规则:

data1         = < any string that doesn't contain a substring that matches not-data1 >
not-data1     = "<!--"    
Run Code Online (Sandbox Code Playgroud)

也就是说,字符串var a = '匹配data1生产.它结束了,因为下一部分是<!--.

为了在脚本中有任何文本,它必须与escape生产相匹配,如下所示:

escape        = "<!--" data2 *( script-start data3 script-end data2 )
Run Code Online (Sandbox Code Playgroud)

让我们匹配文本的下一部分.到目前为止我们有

data1    var a = '
escape   <!--
  data2  ???
Run Code Online (Sandbox Code Playgroud)

现在没有任何东西可以包含在内,data2因为data2生产禁止了子串<script>(即a script-start)!

data2         = < any string that doesn't contain a substring that matches not-data2 >
not-data2     = script-start / "-->"  
Run Code Online (Sandbox Code Playgroud)

词法分析器无法根据语法继续执行有效步骤,因此浏览器现在必须进入错误处理.

  • 我认为HTML5确切地指出了错误处理应该如何工作? (5认同)