我有以下HTML代码:
<script>
function x(){
test1 = '<script><!--';
test2 = '<script>';
}
alert(1);
</script>
<script>
alert(2);
</script>
预期的输出是它会弹出两个警报:alert(1)
和alert(2)
,但是,似乎<!--
注释导致浏览器实际上注释掉了结束</script>
标记,这毫无意义!当我document.getElementsByTagName("script")[0].text
在控制台中运行时,我得到:
function x(){
test1 = '<script><!--';
test2 = '<script>';
}
alert(1);
</script>
<script>
alert(2);
</script>
有这种奇怪行为的解释吗?
谢谢!
从历史上(超过20年前)开始,程序员可以将其脚本代码包装在HTML注释标签中的脚本元素内,以防止不支持脚本标签的浏览器在页面正文中显示脚本文本。您仍然可以在脚本上下文内的脚本周围放置HTML注释标记,这些标记将被忽略:
<script>
<!--
alert(" inside HTML comment tags")
-->
</script>
HTML解析器还负责查找脚本结束标记,</script>
因此它可以将HTML元素的文本内容传递给Javascript引擎以进行语言解析。因此,您必须在未结束脚本块的情况下在JavaScript内容(字符串或注释)中放入未转义的“ </ script>”(HTML解析器首先查看文本)。
该HTML生活水平列出了如何避免问题的一些建议:
避免本节中描述的相当奇怪的限制的最简单,最安全的方法是,始终将ASCII不区分大小写的匹配项“ <!-”替换为“ <\!-”,将“ <script”替换为“ <\ script”当这些序列出现在脚本文字中(例如,字符串,正则表达式或注释中),并且避免在表达式中编写使用此类构造的代码时,“”和“ </ script”分别表示为“ <\ / script”。这样做避免了本节中的限制容易触发的陷阱:即,由于历史原因,HTML脚本块的解析是一种奇怪而奇特的做法,在面对这些序列时会不直观地起作用。
实际上,我发现开放标记在JavaScript中是可以接受的,因为HTML解析器正在寻找结束脚本标记,但是我没有理由抱怨它不能在所有浏览器中都起作用。
因此,推荐的解决方案是在JavaScript代码中反斜杠转义HTML注释定界符。更有趣的是,如果您关闭注释中的HTML注释,它也可以工作-代码按书面形式工作:
<script>
function x(){
test1 = '<script><!--'; // --> close HTML comment
test2 = '<script>';
}
alert(1);
</script>
但是,这符合我的定义,我建议按照标准中的建议转义注释定界符。
TLDR;
<script>
上个世纪,使用两个技巧将标签引入了没有标签的HTML环境(HTML2?):
建议Web作者使用HTML注释定界符以及SGML cdata节声明来开始和结束脚本元素,从而产生内联脚本标签,如下所示:
<script type="text/javascript">
<!-- <![CDATA[
//script content here
// ]]> -->
</script>
这导致HTML解析器不知道脚本元素如何将未知<script>
标签的文本内容视为注释,而不在页面内容中呈现。
这也意味着,当跳过HTML注释文本以查找注释字符的结尾(-->
)时,HTML解析器将很乐意跳过结束脚本标签,否则这些脚本标签将结束它所知道的打开SCRIPT标签。
随着时间的推移和HTML标准的发展,Web作者停止了包括CDATA内容声明,HTML注释声明以及最终导致今天使用的HTML5 JavaScript标记集的type属性:
<script>
// script content here
</sript>
但是,为了不破坏网络,底层的黑客永远不会消失。
确实了解SCRIPT标签的HTML解析器将标签的全部文本内容提供给JavaScript引擎-但仍会跳过未封闭的HTML注释内的最终脚本标签。JavaScript引擎也遭到黑客攻击,可以有效地将HTML注释的打开和空白中的标签定界作为空白的一部分。据我所知,从未在任何地方对此进行记录。您只能通过将脚本包含在HTML注释标签中的外部脚本文件中来推断出黑客行为,并且注意Mozilla Firefox(改编自Netscape Corporation的代码库)不受影响。
发布的脚本启动HTML解析器在行设置中识别的HTML注释temp1
。然后,HTML解析器尝试查找HTML注释的结尾(缺少该注释),并认为script标记无效,因为它没有可检测的结束标记。如果文档的其余部分也不包含该文档,则-->
它也是HTML注释的一部分,并且脚本后的任何正文内容也将不呈现。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句