end-tag open (ETAGO) 定界符
HTML4 中的 ETAGO
HTML 4.01 规范:
尽管
<style>
和<script>
元素使用 CDATA 作为它们的数据模型,但是对于这些元素,用户代理必须以不同方式处理 CDATA。 标记和实体必须被视为原始文本并按原样传递给应用程序。 字符序列</
(ETAGO 或结束标记开放定界符)的第一次出现被视为终止元素内容的结尾。 在有效文档中,这将是元素的结束标记。
附录 B 中的第 3.2.1 节更具体:
当脚本或样式数据是元素(
<script>
和<style>
)的内容时,数据在元素开始标记后立即开始,并在第一个 ETAGO (</
) 定界符后跟名称开始字符 ([a -zA-Z]
); 请注意,这可能不是元素的结束标记。 因此,作者应该在内容中转义</
。 转义机制特定于每种脚本或样式表语言。
(请注意,这仅适用于 HTML 文档中的内联样式和脚本,不适用于从 HTML 引用的外部文件。)
这意味着从技术上讲,以下代码是无效的 HTML4,它不应该工作:
<!-- Remember, this is HTML4 we’re talking about. Redundant @type attributes ftw! -->
<style type="text/css">
p {
background: red;
}
</style>
<style type="text/css">
p {
content: '</abc';
background: green;
}
</style>
第二个 <style>
元素将在解析器到达 ETAGO 定界符时立即关闭,并且不会应用其中的任何样式规则。 段落将获得红色背景颜色(参见第一个 <style>
元素)。 它将等同于以下不一致的标记:
<style type="text/css">
p {
background: red;
}
</style>
<style type="text/css">
p {
content: '
</style>
bc'; background: green; }</style>
<script>
元素也是如此:
<script type="text/javascript">
document.write('<p>Foo</p>');
</script>
根据 HTML4,<script>
元素应该提前关闭,导致 JavaScript SyntaxError
,因为它会被解释如下:
<script type="text/javascript">
document.write('<p>Foo
</script>
');</script>
好吧,这就是理论。 实际上,没有浏览器实现过这一点。 ETAGO 定界符在任何浏览器中都不被视为 <style>
和 <script>
元素的终止序列。我们可以根据上述代码示例查看测试用例,自己轻松确认这一点:<style>
元素内的 ETAGO 定界符和 <script>
元素内的 ETAGO 定界符。
用 HTML5 回到现实
“HTML5”a.k.a. HTML Living Standard 并没有期望现有的实现会发生变化,而是对浏览器已实现的行为进行了标准化(并进行了一些安全改进)。 这在规范中被描述为完整标记化算法的一部分。
这意味着上面的示例现在是有效的 HTML。 当然,它们会一如既往地继续正常工作。 通常,ETAGO 定界符可以用在 <style>
和 <script>
元素内部。 请记住,完整的 </style
和 </script
字符串后跟空格字符 >
或 /
将关闭它们各自的开始标记。
半相关的有趣事实:由于
<title>
元素是一个使用文本内容模型的 RCDATA 元素,因此无需在其中编码<
除非我们想使用</title
后跟任何这些字符。<title>foo < bar</title>
和<title><i>foo</i></title>
根据 HTML 是完全有效的标记。<textarea>
也是如此。 在规范术语中:<script>
和<style>
是原始文本元素,<textarea>
和<title>
是 RCDATA 元素。
为了向后兼容,对于包含 <!- -
且稍后出现 - ->
的 <script>
元素,此规则有一个有趣的例外——在这种情况下,例如 </script>
允许出现在 <script>
元素的内容中。 这是一个有效的工作示例:
<script>
<!--
document.write("<script>alert('LOLWAT')</script>")
-->
</script>
虽然知道这一点很好,但幸运的是,有比这种老式的 90 年代风格模式(无论如何只适用于 <script>
元素)更好的解决方案。 每当我们需要在 <style>
元素内使用 </style>
或在 <script>
元素内使用 </script>
时,只需对这些字符串进行转义即可。 在 CSS 和 JavaScript 中,有多种方法可以做到这一点,但使用反斜杠( \,也称为“反斜线字符”)是迄今为止最简单的方法:
<style>
p {
/* Using the Unicode code point for the solidus character (see https://mths.be/bax): */
content: '<\00002Fstyle>';
/* Using the shorthand notation for Unicode code points (see https://mths.be/bax): */
content: '<\2F style>';
/* Simply escaping the solidus character with a reverse solidus (\): */
content: '<\/style>';
background: green;
}
</style>
<script>
// Using `unescape()`:
document.write(unescape('<script>alert("wtf")%3C/script>')); // Überlame.
// Using string concatenation:
document.write('<script>alert("heh")<' + '/script>'); // Lame.
// Using the octal escape sequence for the solidus character (/):
document.write('<script>alert("hah")<\57script>'); // Lame, deprecated, and disallowed in ES5 strict mode.
// Using the Unicode escape sequence:
document.write('<script>alert("hoh")<\u002Fscript>'); // Lame.
// Using the hexadecimal escape sequence:
document.write('<script>alert("huh")<\x2Fscript>'); // Lame.
// Simply escaping the solidus character:
document.write('<script>alert("O HAI")<\/script>'); // Awesome!
</script>
这两个示例都是有效的 HTML,当然它们可以在任何浏览器中正常工作。
请注意
,虽然这是一种边缘情况,但</script
字符序列理论上可以在 JavaScript 中的字符串之外使用,例如42 </script/
。 当然,简单的\/
转义在这里不起作用。 在这种情况下,请确保在正则表达式文字前使用一个空格:42 < /script/
。 (虽然我想不出 CSS 的这种情况。你能吗?)
建议
HTML 标准现在有一个关于脚本元素内容限制的部分,其中包括以下建议:
避免本节中描述的相当奇怪的限制的最简单和最安全的方法是始终将“
<!- -
”转义为“<\!- -
”,“<script
”转义为“<\script
”,以及“< /script
" 当这些序列出现在脚本的文字中(例如,在字符串、正则表达式或注释中)时,作为 "<\/script
",并避免编写在表达式中使用此类结构的代码。
相关文章
覆盖 Bootstrap CSS
发布时间:2023/04/28 浏览次数:59 分类:CSS
-
本文介绍的是著名的 CSS UI 框架 Bootstrap。 我们将讨论使用自定义样式覆盖 Bootstrap CSS 的过程。
使用 CSS 制作带圆角的 HTML 表格
发布时间:2023/04/28 浏览次数:107 分类:CSS
-
这个简短的文章是关于在 HTML 页面上制作圆角表格的 CSS 样式。使用 CSS 制作带圆角的 HTML 表格 使图像、表格或 div 段的角变圆的属性是 border-radius。
CSS 设置轮廓 outline 的半径
发布时间:2023/04/28 浏览次数:123 分类:CSS
-
在本文中,用户将学习如何为 outline 属性设置圆角,与 border-radius 属性相同。 在这里,我们已经解释了将圆角应用于轮廓属性的不同方法。
使用 CSS 居中视频
发布时间:2023/04/28 浏览次数:73 分类:CSS
-
在本文中,用户将学习仅使用 CSS 将 <video> 元素居中。 我们已经在下面解释了使用 CSS 使视频居中的多种方法。
使用 CSS 居中内联块
发布时间:2023/04/28 浏览次数:108 分类:CSS
-
在本文中,我们将创建多个 HTML 元素并将其显示设置为 inline-block。 之后,我们将学习使用 display: inline-block 将所有元素居中。
使用 CSS 添加透明边框
发布时间:2023/04/28 浏览次数:98 分类:CSS
-
在本文中,我们将讨论在 HTML 中的图像、按钮或任何其他对象周围创建透明边框。 透明边框是图像或对象周围的边框,可改善用户体验。
使用 CSS 向上移动文本
发布时间:2023/04/28 浏览次数:153 分类:CSS
-
有时,在开发网页时,我们将文本放在底部或页脚中,因此我们可能需要在文本下方留一个空格并将文本上移。 我们将学习如何使用 css 从网页底部向上移动文本。
使用 CSS 和 JavaScript 制作文本闪烁
发布时间:2023/04/28 浏览次数:146 分类:CSS
-
本文提供了使用 CSS、JavaScript 和 jQuery 使文本闪烁的详细说明。
CSS 防止文本选择
发布时间:2023/04/28 浏览次数:75 分类:CSS
-
在本文中,我们讨论了防止文本选择和使用具有 none 值的 user-select 属性。 此外,您还将了解如何为不同的 Web 浏览器使用该属性。