HTML 中的字符引用
在解释什么是不明确的 &
符号之前,让我们先谈谈字符引用。
有不同种类的字符引用。 HTML 4.01 规范将它们分为两组,但实际上是三组:
-
十进制数字字符引用,例如
©
-
十六进制数字字符引用,例如
©
-
命名字符引用,例如
©
字符引用应始终以 U+0026 AMPERSAND 字符 (&
) 开头并以 U+003B 分号字符 (;
) 结尾。
有趣的事实:HTML 规范中的命名字符引用列表包括
&
和&
,还有&
和&
(没有尾随分号)。 其他一些实体也是如此。 这样做是出于向后兼容的原因。 这样,规范规定foo & bar
应该呈现为“foo & bar”,即使它是无效标记(因为缺少尾随分号)。 稍后会详细介绍……
在这篇文章中,我们将仔细研究如果在我们的 HTML 代码中有一个未编码的符号不是字符引用的一部分,会发生什么。 有效吗? 无效吗? “模棱两可的符号”与这一切有什么关系?
HTML4 中未编码的符号
HTML 4.01 规范提到了这一点:
提交表单时构建的 URI 可用作锚式链接(例如,
<a>
元素的 href 属性)。 不幸的是,使用&
字符来分隔表单字段与其在 SGML 属性值中用于分隔字符实体引用的使用相互作用。 例如,要使用 URIhttp://host/?x=1&y=2
作为链接 URI,它必须写成<a href="http://host/?x=1&y=2 ">
或<a href="http://host/?x=1&y=2">
。
这意味着如果你想让它有效,你不能只是将 URL 复制粘贴到你的 HTML4 文档中——你必须首先对任何 &
字符进行编码。
HTML5 中的歧义符号
在 HTML5 中,添加了第一个含糊不清的 &
符号的定义:
不明确的
&
符号是 U+0026 AMPERSAND (&
) 字符,它不是文件中的最后一个字符,后面没有空格字符,后面没有没有被省略的开始标记,并且不是 后跟另一个 U+0026 AMPERSAND (&
) 字符。
模棱两可的&
符号是不合格的(无效的); 明确的&
符号通常是一致的(有效的)。 (如前所述:不以分号结尾的命名字符引用中的 &
符号是明确的,但仍然无效。)
换句话说,如果未编码的 &
符号后跟 EOF、空格字符、**<** 或 & ,则它是完全有效的。
根据这个定义,这个例子中的 &
符号都是有歧义的,因此是无效的:
<a href="https://example.com/?x=1&y=2">foo</a>
&123
&abc
foo &0 bar
foo &lolwat bar
然而,这是有效的 HTML:
foo & bar
foo&<i>bar</i>
foo&&& bar
后来规范发生了变化,HTML 规范现在定义了不明确的 &
符号,如下所示:
歧义符号是一个 U+0026 AMPERSAND 字符 (
&
),其后跟一个或多个 U+0030 DIGIT ZERO (0) 到 U+0039 DIGIT NINE (9)、U+0061 拉丁文小写字母 A 到 U+007A 拉丁文小写字母 Z,和 U+0041 拉丁文大写字母 A 到 U+005A 拉丁文大写字母 Z,后跟 U+003B 分号字符 (;),其中这些字符与 命名字符参考部分。
这个定义作为正则表达式可能更容易理解:如果字符串匹配 /&([0-9a-zA-Z]+;)/
并且如果第一个反向引用 ($1
) 不是 已知字符参考。
此示例中的 &
符号都是不明确的,因此无效:
&123;
&abc;
foo &0; bar
foo &lolwat; bar
然而,所有这些都是明确的:
foo & bar
foo&<i>bar</i>
foo&&& bar
<!-- …even the ones that were invalid as per the old definition, are now valid: -->
<a href="http://example.com/?x=1&y=2">foo</a>
&123
&abc
foo &0 bar
foo &lolwat bar
使用新定义,这是完全有效的 HTML——尽管我所知道的 HTML 验证器还没有识别出这一点。
所以我们已经确定并不是所有的符号字符都需要在 HTML 中转义。 半相关的有趣事实:在大多数情况下,也不需要转义
>
字符。 它没有特殊含义(因此是明确的),除非它是标记的一部分或未加引号的属性值。 例如,<p>foo > bar</p>
是完全有效且可靠的 HTML。
造成歧义的本质原因
如前所述,一些命名字符引用在没有尾随分号(例如 &
)的情况下工作,即使它是无效标记。 更复杂的是,这些实体在属性值中的处理方式不同。
如果字符引用作为属性的一部分使用,并且最后匹配的字符不是 U+003B 分号字符 (
;
),并且下一个字符是 U+003D 等号字符 (=
) 或字母数字 ASCII 字符,那么,由于历史原因,在 U+0026 AMPERSAND 字符 (&
) 之后匹配的所有字符必须是未使用的,并且不返回任何内容。 但是,如果下一个字符实际上是 U+003D EQUALS SIGN 字符 (=
),那么这是一个解析错误,因为在这些情况下,某些旧版用户代理会误解标记。
以这个(显然无效的)HTML 为例:
<p title="foo&bar">
foo&bar
</p>
在浏览器中尝试一下。 你会看到段落的文本内容显示为“foo&bar”,而标题属性值显示为“foo&bar”。
总结一下:未编码的 &
符号(有时有效)、模糊的 &
符号(始终无效)和编码的 &
符号(始终有效)之间存在差异。 未编码的 &
符号并不总是有歧义的 &
符号。 明确的 &
符号仍然无效。
在我看来,这有点令人困惑。 但它不一定是! 如有疑问,只需对你的 effin 符号进行编码。
对于希望处理 HTML 实体的库开发者来说,了解什么是不明确的 &
符号以及它们的工作原理尤为重要。 不考虑这些边缘情况可能会导致代码中出现 XSS 或其他安全漏洞。
相关文章
HTML 中的 role 属性
发布时间:2023/05/06 浏览次数:124 分类:HTML
-
本篇文章介绍 HTML role属性。HTML中 role 属性介绍,role 属性定义描述语义的 HTML 元素的角色。
在 HTML 中打印时分页
发布时间:2023/05/06 浏览次数:188 分类:HTML
-
本篇文章介绍如何在打印 HTML 页面或内容时强制分页。将 page-break-after 属性设置为 always Inside @media print to Page Break in HTML
在 HTML 中显示基于 Cookie 的图像
发布时间:2023/05/06 浏览次数:154 分类:HTML
-
本文介绍如何根据 HTML 中的 cookies 显示图像。根据 HTML 中设置的 Cookies 显示图像。问题陈述是我们需要根据网页传递的cookie来显示特定的图像。
在 HTML 中创建下载链接
发布时间:2023/05/06 浏览次数:140 分类:HTML
-
本文介绍如何在 HTML 中创建下载链接。使用 download 属性在 HTML 中创建下载链接.。我们可以使用 HTML 锚元素内的下载属性来创建下载链接。
HTML 中的 ::before 选择器
发布时间:2023/05/06 浏览次数:70 分类:HTML
-
本教程介绍 CSS ::before 伪元素。CSS ::before 伪元素。 ::before 选择器是一个 CSS 伪元素,我们可以使用它在一个或多个选定元素之前插入内容。 它默认是内联的。
在 HTML 中创建一个可滚动的 Div
发布时间:2023/05/06 浏览次数:54 分类:HTML
-
本篇文章介绍如何使 HTML div 可滚动。本文将介绍在 HTML 中使 div 可滚动的方法。 我们将探索垂直和水平滚动,并通过示例查看它们的实现。
HTML 显示箭头的代码
发布时间:2023/05/06 浏览次数:153 分类:HTML
-
一篇关于用于显示箭头的 Unicode 字符实体的紧凑文章。本文讨论使用 Unicode 字符实体在我们的 HTML 页面上显示不同的字符。 HTML 中使用了许多实体,但我们将重点学习表示上、下、左、右的三角
在 HTML 中启用和禁用复选框
发布时间:2023/05/06 浏览次数:149 分类:HTML
-
本篇文章介绍如何启用和禁用 HTML 中的复选框。HTML 中的复选框 复选框是一个交互式框,可以切换以表示肯定或否定。 它广泛用于表单和对话框。
HTML 中的只读复选框
发布时间:2023/05/06 浏览次数:198 分类:HTML
-
本篇文章介绍了如何在 HTML 中制作只读复选框。本文是关于如何使 HTML 复选框控件成为只读组件的快速破解。 但是,首先,让我们简要介绍一下复选框控件。