【问题标题】:Extremely strange glitch in Chrome - parses contents of string!Chrome 中极其奇怪的故障 - 解析字符串的内容!
【发布时间】:2011-02-11 09:37:07
【问题描述】:

好的 - 这是我一段时间以来见过的最愚蠢的故障:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type='text/javascript'>

var data = "</script>";

</script>
</head>
<body>

This should break!

</body>
</html>

这会导致语法错误,因为 JavaScript 解析器实际上正在读取字符串的内容。多么愚蠢!

如何将&amp;lt;/script&amp;gt; 放入我的代码中。有什么办法吗?

这种行为有正当理由吗?

【问题讨论】:

  • 转义有什么问题?不仅仅是 Chrome。我在 Windows 7 上的 Firefox 3.6 上对其进行了测试,它也给出了同样的错误结果。
  • 逃跑?喜欢&amp;lt;/script&amp;gt;?那也没用。
  • @Xavier Ho:结果是正确的,预期是错误的。
  • 那么期望是什么?
  • 关键是HTML没有定义一个单独的脚本类型来解析字符串,并且在字符串中HTML标签是无效的。当它看到&lt;script&gt; 时,它只会查找&amp;lt;/script&amp;gt; - 它并不关心脚本中的字符串可能是什么,也可能不是。

标签: javascript html google-chrome html-parsing


【解决方案1】:

如果你能相信the HTML4 standard,脚本内容

在第一个 ETGO ("") 分隔符处结束,后跟名称开始字符 ([a-zA-Z])

所以,JavaScript 解析器并没有像您描述的那样读取字符串的内容; JavaScript 解析器在 var data = " 之后永远不会得到任何东西,这显然不是一个有效的脚本。

避免意外提前结束 JavaScript 的最简单方法是使用 Andy E 的第一个建议:

var data = "<\/script>"; 

这样,HTML 解析器看不到&lt;/,因此脚本内容不会结束,\/ 等效于 JavaScript 字符串文字中的 /,因此结果是正确的。这也是标准中针对 JavaScript 显示的方法。

【讨论】:

    【解决方案2】:

    在 X(HT)ML 中(当 actually treated as such 时),正是出于这个原因,需要将脚本转义为 CDATA。 http://www.w3.org/TR/xhtml1/diffs.html#h-4.8

    在 XHTML 中,脚本和样式元素被声明为具有#PCDATA 内容。因此,&amp;lt;&amp;amp; 将被视为标记的开始,而诸如&amp;lt;&amp;amp; 之类的实体将被XML 处理器识别为分别对&amp;lt;&amp;amp; 的实体引用.将脚本或样式元素的内容包装在 CDATA 标记的部分中可避免这些实体的扩展。

    <script type="text/javascript">
    <![CDATA[
      ... unescaped script content ...
    ]]>
    </script>
    

    如果您的 XHTML 文档只是用作 text/html 并被视为标签汤,则不适用,您只需“转义”字符串,如 '&lt;/scr' + 'ipt&gt;'

    【讨论】:

    • CDATA...哦,是的。我忘记了。我总是用 ActionScript 来做。忘了你可以用 JavaScript 做到这一点...... :)
    • 啊。我知道了。那好吧。您提出的其他解决方案似乎没问题。
    【解决方案3】:

    这不是故障 - 这是正常的预期行为,如果您考虑一下,这是完全正确的。 HTML 规范没有定义脚本语言,所以引擎应该看到的只是纯文本,直到 &lt;/script&gt; 关闭标签。除了已经列出的选项之外,还有几个选项:

    // escape the / character, changing the format of the "closing" tag
    var data = "<\/script>"; 
    
    // break up the string
    var data = "</"+"script>";
    

    第一种方法有效,因为 HTML 不使用 \ 进行转义,它被视为文字字符,当然 &lt;\/script&gt; 不是有效的结束标记。第二个的工作原理更明显,但是这里的其他人告诉我不应该使用它(而且我一直不太明白为什么)。

    【讨论】:

    • 第二个似乎工作正常。我也不知道为什么我不会用它。
    • @George:无论如何,第一个对我来说更可取,分解两个字符串文字感觉不对;-)
    【解决方案4】:

    这样写:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    <script type='text/javascript'>
    <!--
    var data = "</script>";
    -->
    </script>
    </head>
    <body>
    This should break!
    </body>
    </html>
    

    原因很简单,就是在执行 javascript 之前解析 HTML,而 &lt;!----&gt; 使解析器忽略此部分中出现的所有标记。

    【讨论】:

    • 如果您的脚本在字符串中包含"--&gt;" 怎么办? ;-)
    猜你喜欢
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 2018-01-25
    相关资源
    最近更新 更多