ChatGPT解决这个技术问题 Extra ChatGPT

我真的需要将'&'编码为'&'吗?

我在我网站的 <title> 中使用了带有 HTML5 和 UTF-8 的“&”符号。 Google 在其 SERPs 上显示与号罚款,所有浏览器在其标题中也是如此。

http://validator.w3.org 给了我这个:

& 没有开始字符引用。 (& 可能应该被转义为 &.)

我真的需要做&amp;吗?

我不会为了验证而对我的页面进行验证,但我很想听听人们对此的看法,以及它是否重要以及为什么重要。

规格没有这样说。海报指的是 HTML5,它不需要在所有场景中转义 & 符号。
这应该是社区 Wiki,因为您正在寻找意见,并且对验证不挑剔意味着没有客观的基础可以回答。
@理查德:真的吗?虽然我不同意“验证无关紧要”,但我认为这是一个非常客观的问题:“这会破坏规范以外的任何内容吗?”
@Richard:我不同意这里。 “我真的需要做&amp;吗?”和“[...]我很想听听人们对此的看法,以及它是否重要以及为什么重要。” (强调我的)。这两个表明他对事实信息感兴趣,但知道其中大部分内容至少可以进行一些解释,因此他要求提供多种意见。
HTML 规范说接受废话输入。这是否意味着您的网站现在被“允许”成为垃圾?关闭需要关闭的标签并逃避事情!来人吧。

D
Delan Azabani

是的。正如错误所说,在 HTML 中,属性是 #PCDATA 表示它们已被解析。这意味着您可以在属性中使用字符实体。单独使用 & 是错误的,如果不是针对宽松的浏览器以及这是 HTML 而不是 XHTML 的事实,将会破坏解析。只需将其作为 &amp; 转义,一切都会好起来的。

HTML5 允许您将其保留为不转义,但前提是后面的数据看起来不像是有效的字符引用。然而,最好只是逃避这个符号的所有实例,而不是担心哪些应该是,哪些不需要。

记住这一点;如果您没有将 & 转义为 &,那么对于您创建的数据(代码很可能无效)已经够糟糕了,您也可能没有转义标签分隔符,这对于用户提交的数据来说是一个大问题,这很可能导致 HTML 和脚本注入、cookie 窃取和其他漏洞利用。

请转义您的代码。以后可以省去很多麻烦。


任何浏览器都不会“曲解” & 本身。每个现有浏览器都将其显示为“&”。考虑到他明确要求这样做是出于实际原因,并且他说他不关心验证..
是的。但在道德上,我们是否应该依赖浏览器的宽大处理和“好的”错误处理?还是我们应该只写正确的代码?
@Delan:虽然我试图让我写的每一页都有效,但我从阅读他的问题中了解到他并不关心“道德”。他只关心它是否有效。它们是两种不同的哲学,各有利弊,没有“正确”的。例如,这个网站没有验证,但它是一个很棒的网站。
@Andreas,但是浏览器在解释正确代码的方式上存在足够多的错误,这取决于当您向它们发送无意义的标记时它们是否会获得正确的结果。它今天可能适用于该示例,然后在下一个示例中失败(例如,如果下一个示例在 & 之后的某处有分号)
每个人似乎都在谈论 HTML5,但最初的问题表明 HTML5 正在使用中。在这种情况下,HTML5 明确允许未转义的 &,除非 & 后面的内容通常会扩展为实体(例如 ©=2 有问题,但 &x=2 很好)。
P
Peter Mortensen

撇开验证不谈,对某些字符进行编码对于 HTML 文档很重要,这样它才能正确安全地呈现为网页。

对我来说,在任何情况下都将 & 编码为 &amp; 是一个更容易遵守的规则,可以减少出错和失败的可能性。

比较以下:哪个更容易?哪个更容易出轨?

方法1

写一些包含 & 字符的内容。将它们全部编码。

方法2

(请加一粒盐;))

写一些包含 & 字符的内容。根据具体情况,查看每个 & 符号。确定是否:

它是孤立的,因此毫无疑问是一个&符号。例如。伏特和安培> 在这种情况下,不要费心对其进行编码。

它不是孤立的,但您仍然觉得它是明确的,因为生成的实体不存在并且永远不会存在,因为实体列表永远不会发展。例如,安培&伏特>。在这种情况下,不要费心对其进行编码。

它不是孤立的,也不是模棱两可的。例如,volt& > 对其进行编码。

??


amp&volt is 的第二种情况不明确:&volt 现在是否是实体引用?
@Gumbo amp&volt 中的 & 号 不是 模棱两可的 & 号(根据 HTML 规范中的定义)。请参阅 mathiasbynens.be/notes/ambiguous-ampersandsmothereff.in/ampersands#amp%26volt
@MathiasBynens 到现在(2019 年),definition of an ambiguous ampersand 似乎与您在 2011 年在 mathiasbynens.be/notes/ambiguous-ampersands 中引用的定义有所不同。
M
Matthew Wilson

HTML5 规则与 HTML4 不同。它在 HTML5 中不是必需的 - 除非符号看起来像是一个参数名称的开头。 "©=2" 仍然是一个问题,例如,因为 ©是版权符号。

但是,在我看来,根据以下文本决定编码或不编码是一项更难的工作。所以最简单的方法可能是一直编码。


这就像引用属性值——你不必这样做,但如果你一直这样做就不会出错。
&copy=2 并没有您想象的那么大。在属性值(例如 href 属性)中,&copy 不会被视为 © 的字符引用。在属性值之外,它会。
鉴于 & 符号在英文文本中通常前后都有一个空格,不难记住或思考我遵循的规则:如果 & 符号没有触及另一个可见字符,几乎总是这样,那么它不需要编码。否则,只是为了简单起见进行编码。
您能否添加对 HTML5 规则的引用?
我相信 &copy= 从来都不是问题,因为 Xml 实体始终具有结构 &...; - 它们必须以 ; 结尾 - 否则它不是 Xml 实体。我仍然同意安全比过度优化风险要好。
R
Ryan Kinal

我认为这已经变成了一个“当浏览器不在乎时为什么要遵循规范”的问题。这是我的笼统回答:

标准不是“现在”的东西。它们是“未来”的东西。如果我们作为开发人员遵循 Web 标准,那么浏览器供应商更有可能正确实施这些标准,并且我们更接近于完全可互操作的 Web,其中 CSS hack、特性检测和浏览器检测不是必需的。我们不必弄清楚为什么我们的布局会在特定浏览器中中断,或者如何解决这个问题。

具体来说,如果 HTML5 不需要使用 &在您的特定情况下,并且您使用的是 HTML5 文档类型(并且还希望您的用户使用符合 HTML5 的浏览器),那么没有理由这样做。


话虽如此,一般来说,您必须记住,大多数“标准”方式仍处于草稿模式,将来可能会发生变化。
P
Peter Mortensen

好吧,如果它来自用户输入,那么绝对是的,原因很明显。想想如果这个网站没有这样做:这个问题的标题会显示为我真的需要将'&'编码为'&'吗?

如果它只是像 echo '<title>Dolce & Gabbana</title>'; 这样的东西,那么严格来说你不必这样做。这会更好,但如果你不这样做,用户将不会注意到差异。


为什么会更好?
A
AakashM

你能告诉我们你的title到底是什么吗?当我提交

<!DOCTYPE html>
<html>
<title>Dolce & Gabbana</title>
<body>
<p>Am I allowed loose & mpersands?</p>
</body>
</html>

http://validator.w3.org/ - 明确要求它使用实验性 HTML 5 模式 - 它对 & 没有任何抱怨...


是的,HTML5 的解析器与以前的 HTML 和 XHTML 解析器不同,并且在某些情况下允许使用未转义的 & 符号。
就这些示例而言,这在 HTML5 中并不是什么新鲜事。 <title>Dolce & Gabbana</title><p>Dolce & Gabbana</p> 都是有效的 HTML 2.0。
P
Peter Mortensen

在 HTML 中,& 标记引用的开始,无论是 character reference 还是 entity reference。从那时起,解析器需要一个表示字符引用的 # 或表示实体引用的实体名称,两者后跟一个 ;。这是正常的行为。

但是,如果引用名称或仅引用开头 & 后跟空格或其他分隔符,如 "'<>&、结尾 ; 甚至表示普通的引用,& 可以省略:

<p title="&amp;">foo &amp; bar</p>
<p title="&amp">foo &amp bar</p>
<p title="&">foo & bar</p>

只有在这些情况下,才能省略结尾 ; 甚至引用本身(至少在 HTML 4 中)。我认为 HTML 5 需要结尾 ;

specification recommends 始终使用字符引用 &#38; 或实体引用 &amp; 之类的引用以避免混淆:

作者应使用“&” (ASCII 十进制 38)而不是“&”以避免与字符引用的开头混淆(实体引用打开分隔符)。作者还应该使用“&”在属性值中,因为在 CDATA 属性值中允许字符引用。


那是您链接到的 HTML 4 规范;根据我对(草稿)HTML 5 规范的阅读,只有模棱两可的 & 号是不允许的。例如,后跟空格的 & 符号不是模棱两可的,因此(再次通过我的阅读)应该被允许 - 请参阅我对 HTML 5 验证器接受的标记的回答。
@AakashM:我不确定,听起来像那样。
P
Peter Mortensen

这取决于分号出现在 & 附近的可能性,从而导致它显示完全不同的内容。

例如,在处理来自用户的输入时(例如,如果您在标题标签中包含用户提供的论坛帖子主题),您永远不知道他们可能会在哪里放置随机分号,并且它可能会随机显示奇怪的实体。所以总是在那种情况下逃脱。

当然,对于您自己的静态 HTML 内容,您可以跳过它,但是包含正确的转义是如此微不足道,因此没有充分的理由避免它。


P
Peter Mortensen

如果用户将其传递给您,或者它将以 URL 形式结束,您需要对其进行转义。

如果它出现在页面上的静态文本中?无论哪种方式,所有浏览器都会正确使用它,您不必担心它,因为它会起作用。


P
Peter Mortensen

更新(2020 年 3 月):W3C 验证器不再抱怨转义 URL。

我正在检查为什么 image URL 需要转义,因此在 https://validator.w3.org 中进行了尝试。解释很不错。它强调即使是 URL 也需要转义。 [PS:我猜它在使用时不会转义,因为 URL 需要 &。谁能澄清一下?】

<img alt="" src="foo?bar=qut&qux=fop" />

在文档中找到实体引用,但没有定义该名称的引用。这通常是由拼写错误的引用名称、未编码的 & 号或遗漏尾随分号 (;) 引起的。此错误的最常见原因是 URL 中未编码的 & 符号,如 WDG 在“URL 中的符号”中所述。实体引用以和号 (&) 开头,以分号 (;) 结尾。如果您想在文档中使用文字 & 符号,则必须将其编码为“&”(即使在 URL 中!)。请注意以分号结束实体引用,否则您的实体引用可能会被解释为与以下文本相关。还要记住,命名实体引用是区分大小写的; &Aelig;和 æ 是不同的字符。如果此错误出现在 PHP 的会话处理代码生成的某些标记中,本文对您的问题进行了解释和解决方案。


阅读票数最高的答案。属性是#PCDATA,因此会被解析。实体在那里处理。在您的示例中,& 启动实体引用。读取 &qux 后,解析器没有找到最后的分号 (;),而是遇到了一个等号 (=),它不能是实体名称的一部分。如果解析器试图非常严格(根据 HTML 4),这应该是解析错误。在 HTML 5 中,实体解析总体上更加轻松。
我怀疑通常最好使用 ; 作为查询字符串中的分隔符(当您控制链接时)。
P
Peter Mortensen

是的,如果可能,您应该尝试提供有效代码。

大多数浏览器都会默默地纠正这个错误,但是依赖浏览器中的错误处理存在问题。对于如何处理不正确的代码没有标准,因此每个浏览器供应商都需要尝试弄清楚如何处理每个错误,结果可能会有所不同。

浏览器可能做出不同反应的一些示例是,如果您将元素放在表格内部但表格单元格外部,或者如果您将链接嵌套在彼此内部。

对于您的特定示例,它不太可能导致任何问题,但浏览器中的错误更正可能会导致浏览器从标准兼容模式更改为 quirks mode,这可能会使您的布局完全崩溃。

因此,您应该更正代码中的此类错误,如果不是为了其他任何原因,请保持验证器中的错误列表简短,以便您发现更严重的问题。


P
Peter Mortensen

几年前,我们收到报告称我们的一个网络应用程序在 Firefox 中无法正确显示。原来,该页面包含一个看起来像的标签

<div style="..." ... style="...">

当面对重复的样式属性时,Internet Explorer 结合了这两种样式,而 Firefox 只使用其中一种,因此行为不同。我将标签更改为

<div style="...; ..." ...>

果然,它解决了问题!这个故事的寓意是浏览器对有效 HTML 的处理比对无效 HTML 的处理更加一致。所以,已经修复了你该死的标记! (或使用 HTML Tidy 修复它。)


P
Peter Mortensen

如果在 HTML 中使用了 &,那么您应该对其进行转义。

如果在 JavaScript 字符串中使用 &,例如 alert('This & that');document.href,则不需要使用它。

如果您使用的是document.write,那么您应该使用它,例如document.write(<p>this &amp; that</p>)


document.write 应该避免。请参阅 w3.org/html/wg/drafts/html/master/dom.html#document.write%28%29 中的警告框
关于document.write()的好点。但亚历克斯关于从脚本站写入文档的全部要点,imo。 +1
J
Joachim Sauer

如果你真的在谈论静态文本

<title>Foo & Bar</title>

存储在硬盘上的某个文件中并由服务器直接提供服务,那么是的:它可能不需要转义。

但是,由于现在很少有 HTML 内容是完全静态的,我将添加以下免责声明,假设 HTML 内容是从其他来源(数据库内容、用户输入、Web 服务调用结果、旧版 API 结果、. ..):

如果您不转义简单的 &,那么您很可能也不会转义 &amp;&nbsp;<b><script src="http://attacker.com/evil.js"> 或任何其他无效文本。这意味着您充其量只是错误地显示了您的内容,并且更有可能被 XSS attacks 怀疑。

换句话说:当您已经在检查和转义其他更成问题的案例时,几乎没有理由让未完全损坏但仍然有些可疑的独立 - & 未转义。


我没有投反对票,但如果我不得不猜测,我会说你被投反对票是因为你的回答(虽然很聪明)与问题有点不匹配。他不是在询问转义用户输入的问题。他可以控制角色,基本上是在问“如果它符合我的要求,那么严格遵守语言规范真的很重要吗?”即,他知道有一个 & 因为他把它放进去了。
@Matt:我明白了,那是合理的。我只是假设没有人再编写完全静态的 HTML 页面,并且几乎所有内容至少在某种程度上是动态的(通常基于某些数据库内容)。也许这个假设应该明确。
m
mathin

该链接有一个很好的示例,说明您何时以及为何需要将 & 转义为 &amp;

https://jsfiddle.net/vh2h7usk/1/

有趣的是,为了在我的回答中正确地表示它,我不得不转义这个角色。如果我要使用内置的 code sample 选项(来自答案面板),我只需输入 &amp;,它就会出现。但是如果我要手动使用 <code></code> 元素,那么我必须转义才能正确表示它:)