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


207

我在网站的中使用&带有HTML5和UTF-8 的' '符号<title>。Google会在其SERP上显示“&”号罚款,标题中的所有浏览器也一样。

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

&没有启动字符引用。(&可能应该以进行转义&amp;。)

我真的需要做&amp;吗?

我不必为验证页面而对页面验证感到困惑,但我很好奇,希望听到人们对此的看法,以及它是否重要以及为什么。


63
规格没有这么说。张贴者指的是HTML5,它不需要在所有情况下都转义“&”号。
马修·威尔逊

2
当您在寻找意见时,这应该是Community Wiki,并且不要对验证过于挑剔,这意味着没有客观的答案依据。
理查德JP Le Guen

6
@理查德:真的吗?尽管我不同意“验证无所谓”,但我认为这是一个非常客观的问题:“这会破坏规范以外的其他内容吗?”
约阿希姆·绍尔

2
@YiJiang 当前的网络浏览器全力以赴地了解用户Google也是如此。这是规范的一部分。未来的网络浏览器可能不会那么宽容。因此,检查并复制Wikipedia总是一个好主意。
unixman83 '02

2
HTML规范说接受废话输入。这是否意味着您的网站现在“被允许”废话?关闭需要关闭的标签并转义!加油
doug65536 '16

Answers:


143

是。就像错误所说的那样,在HTML中,属性是#PCDATA,表示它们已被解析。这意味着您可以在属性中使用字符实体。单独使用&是错误的,如果不是宽松的浏览器,并且使用HTML而不是XHTML的事实会破坏解析。只要逃脱它&amp;,一切都会好起来的。

HTML5允许您不对其进行转义,但是仅当其后的数据看起来不像是有效的字符引用时。但是,最好不要使用该符号的所有实例,而不必担心应该是哪个实例,而不必担心哪个实例。

请记住这一点;如果您不转义&到&amp ;,对于您创建的数据来说已经很糟糕了(代码很可能是无效的),那么您也可能不会转义标签定界符,这对于用户提交的数据来说是一个巨大的问题,这很可能导致HTML和脚本注入,cookie窃取和其他攻击。

请转义您的代码。它将为您节省很多麻烦。


9
没有浏览器会单独“误解”&。每个现有的浏览器都将其显示为“&”。考虑到他明确要求实际的理由这样做,他说他不关心验证..
托马斯博尼尼

47
是。但是从道德上讲,我们应该依靠浏览器的宽大处理和“不错的”错误处理吗?还是我们应该编写正确的代码?
Delan Azabani

8
@Delan:当我尝试使我编写的每个页面都通过验证时,我从阅读他的问题中了解到他不在乎“道德”。他只是在乎它是否起作用。它们是两种不同的哲学,各有优缺点,没有“正确的”哲学。例如,此网站未通过验证,但它是一个很棒的网站。
Thomas Bonini 2010年

3
@Andreas,但是浏览器在解释正确代码方面有很多错误,这取决于它们在向您发送无意义的标记时是否获得正确的结果是无能为力的。它可能今天在该示例中有效,然后在下一个示例中失败(例如,下一个示例是否在&之后加上分号)
Jon Hanna 2010年

11
每个人似乎都在谈论HTML5,但最初的问题是HTML5正在使用中。在这种情况下,HTML5明确允许未转义的&,除非遵循&通常会扩展为实体(例如,&copy = 2是有问题的,但&x = 2是可以的)。
马修·威尔逊

55

除了验证之外,事实仍然是编码某些字符对于HTML文档很重要,这样它就可以正确安全地呈现为网页。

编码&&amp;在任何情况下,对我来说,是生活,减少错误和失败的可能性更简单的规则。

比较以下内容:哪个更容易?哪个更容易打扰

方法1

  1. 编写一些包含“&”字符的内容。
  2. 全部编码。

方法2

(请加一粒盐;))

  1. 编写一些包含“&”字符的内容。
  2. 视情况而定,查看每个“&”号。确定是否:
    • 它是孤立的,因此是一个明确的“&”号。例如。volt & amp
       >在那种情况下,请不要对它进行编码。
    • 它不是孤立的,但是您会感到它是明确的,因为生成的实体不存在,并且由于实体列表永远不会演化而将永远不存在。例如:amp&volt
       >那样的话,就不用编码了。
    • 它不是孤立的,模棱两可的。例如。volt&amp
       >对其进行编码。

??


3
第二种情况amp&volt 模棱两可的:&volt现在是实体引用吗?
浓汤

6
@Gumbo的符号中amp&volt暧昧符号(按照定义在HTML规范)。参见mathiasbynens.be/notes/ambiguous-andsandsmothereff.in/ampersands#amp%26volt
Mathias Bynens 2012年

@MathiasBynens到现在(2019年),歧义的&符号定义似乎与您在2011年在mathiasbynens.be/notes/ambiguous-ampersands中引用的定义有所不同
雅各布·C(Jacob C.)说应

21

HTML5规则不同于HTML4。HTML5中不需要它-除非“&”号看起来像是一个参数名。例如,由于&copy;,“&copy = 2”仍然是个问题。是版权符号。

但是在我看来,根据以下文本来决定编码还是不编码比较困难。因此,最简单的途径可能是一直进行编码。


2
这就像引用属性值一样,您不必这样做,但是如果始终这样做,就不会出错。
Paul D. Waite,2010年

3
&copy=2并不是您可能想到的那么大的问题。在属性值(例如href属性)中,&copy不会被视为的字符引用©。在属性值之外,它将。
Mathias Bynens 2013年

鉴于在英文文本中通常在与号之前和之后加上空格,因此记住或遵循我遵循的规则并不难:如果“与”号没有碰到另一个几乎总是可见的字符,那么就不需要编码。否则,只是为了简单起见就进行编码。
卡尔·史密斯

您可以添加对HTML5规则的引用吗?
Ferrybig

17

我认为这已经变成了一个更多的问题:“当浏览器不在乎时,为什么要遵循规范”。这是我的广义答案:

标准不是“现在”的事情。他们是“未来”的事情。如果我们作为开发人员遵循Web标准,那么浏览器供应商将更有可能正确实施这些标准,因此我们将向完全可互操作的Web靠拢,而CSS hack,功能检测和浏览器检测则是不必要的。我们不必弄清楚为什么在特定的浏览器中布局会中断,或者如何解决该问题。

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


1
话虽如此,通常来说,您必须记住,大多数“标准”方式仍处于草稿模式,并且将来可能会发生变化。
refaelio 2014年

6

好吧,如果它来自用户输入,那么出于显而易见的原因,绝对是的。想想这个网站是否没有做:这个问题的标题会显示出来,因为我真的需要将“&”编码为“&”吗?

如果只是这样,echo '<title>Dolce & Gabbana</title>';那么严格来说您不必这样做。这样做会更好,但是如果您不这样做,那么没有用户会注意到差异。


5

您能告诉我们您的title实际身份吗?当我提交

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

http://validator.w3.org/ - 明确要求它使用实验HTML 5模式 -它没有对投诉&小号...


1
是的,HTML5的解析器与以前的HTML和XHTML解析器不同,并且在某些情况下允许使用非转义的“&”号。
kevinji 2011年

就这些示例而言,这在HTML5中并不是什么新鲜事物。这两个<title>Dolce & Gabbana</title><p>Dolce & Gabbana</p>是有效的HTML 2.0。
Mathias Bynens'1

4

在HTML中,a &表示字符引用实体引用的引用的开始。从这一点出发,解析器期望#表示字符引用或表示实体引用的实体名称,后跟一个;。这是正常现象。

但是,如果参考名称或只是参考开口&后跟一个空格或其他分隔符喜欢"'<>&,结束;和甚至一个参考来表示一个普通的&可省略:

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

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

但是规范建议始终使用诸如字符参考&#38;或实体参考之类的参考&amp;以避免混淆:

作者应使用“ &amp;”(ASCII十进制38)而不是“ &”,以避免与字符参考(实体参考开放分隔符)的开头混淆。&amp;由于在CDATA属性值中允许使用字符引用,因此作者也应在属性值中使用“ ”。


1
这就是您链接到的HTML 4规范;从我对HTML 5规范(草稿)的阅读中,只能禁止歧义的“&”号。例如,“&”号后面没有空格,这并不是模棱两可的,因此(同样是我的阅读)应该被允许-有关HTML 5验证程序接受的标记的信息,请参见我的答案。
AakashM 2010年

1
@AakashM:我不确定,听起来像那样。
Gumbo 2010年

3

如果用户将其传递给您,或者它将显示在URL中,则需要对其进行转义。

是否以静态文本显示在页面上?所有浏览器都会以一种正确的方式实现这一目标,您不必为此担心,因为它可以工作。


3

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

我正在检查为什么需要转义图像URL,因此在https://validator.w3.org中尝试了它。解释很不错。它强调甚至URL也需要转义。[PS:我想由于URL的需要,它在被消耗时不会消失&。有人可以澄清吗?]

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

在文档中找到了实体引用,但没有定义该名称的引用。通常,这是由于拼写错误的参考名称,未编码的与号或省略尾随的分号(;)引起的。导致此错误的最常见原因是URL中的未编码的“&”号,如WDG在“ URL中的符号”中所述。实体引用以与号(&)开头,以分号(;)结尾。如果要在文档中使用文字“&”号,则必须将其编码为“&”(甚至在URL中!)。小心以分号结尾的实体引用,否则您的实体引用可能会与以下文本联系在一起进行解释。还请记住,命名实体引用区分大小写;&Aelig; 和æ是不同的字符。


1
阅读投票最多的答案。属性为#PCDATA,因此已解析。实体在那里处理。在您的示例中,&启动实体引用。阅读后&qux,解析器找不到最终的分号(;),但遇到等号(=),该等号不能是实体名称的一部分。如果解析器尝试非常严格(根据HTML 4),则这应该是解析错误。在HTML 5中,实体解析总体上更加轻松。
Palec

1
我怀疑通常由于这个原因,最好;在查询字符串中使用分隔符(当您控制链接时)。
黛咪

2

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

大多数浏览器会静默纠正此错误,但是依靠浏览器中的错误处理存在问题。没有处理错误代码的标准,因此,由每个浏览器供应商决定如何处理每个错误,结果可能会有所不同。

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

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

因此,您应该在代码中更正这样的错误,如果没有其他原因,则应使错误列表在验证器中更短,以便发现更严重的问题。


2

几年前,我们收到一份报告,说我们的一个Web应用在Firefox中无法正确显示。原来,该页面包含一个看起来像

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

当面对重复的样式属性时,IE会将两种样式组合在一起,而Firefox仅使用其中一种样式,因此行为有所不同。我将标签更改为

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

当然可以解决问题!这个故事的寓意是,与无效HTML相比,浏览器对有效HTML的处理更为一致。因此,已经修复了该死的标记!(或使用HTML Tidy对其进行修复。)



1

这取决于分号出现在您附近的可能性&,导致分号显示出完全不同的东西。

例如,在处理来自用户的输入时(例如,如果您在标题标签中包含用户提供的论坛帖子主题),您将永远不知道他们在哪里放置随机分号,并且它可能会随机显示奇怪的实体。因此,在这种情况下请始终躲避。

当然,对于您自己的静态html,您可以跳过它,但是包含适当的转义太简单了,因此没有充分的理由避免它。


0

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

<title>Foo & Bar</title>

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

但是,由于是非常小的HTML内容时下是完全静态的,我将添加下面的免责声明是假设HTML内容是从其他来源(数据库内容,用户输入的Web服务调用的结果,遗留API的结果产生。 ..):

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

换句话说:当您已经检查并逃避了其他更成问题的案例时,几乎没有理由将尚未完全破损但仍然有些腥的单机和逃脱。


2
我没有投票,但是,如果我不得不猜测,我会说您被投票了,因为您的答案(虽然很聪明)与问题有点不符。他并不是在询问如何转义用户输入。他控制了角色,并且基本上是在问:“如果它能满足我的要求,那么遵循字母的语言规范真的很重要吗?” 即,他知道有一个&,因为他将其放入
Matt

@马特:我明白了,那是合理的。我只是假设没有人再写完全静态的HTML页面,并且几乎所有内容至少都是动态的(通常基于某些数据库内容)。也许该假设应该明确。
约阿希姆·绍尔

-1

不知道这是否对任何人有用...我已经为此战斗了一段时间...这是一个光荣的正则表达式,您可以使用它来修复所有链接,javascript,内容。我不得不处理大量的遗留内容,没人想纠正。

将此添加到母版页或控件中的“渲染”替代中:

请不要因为将其放置在错误的位置而解雇我:

// remove the & from href="blaw?a=b&b=c" and replace with &amp; 
//in urls - this corrects any unencoded & not just those in URL's
// this match will also ignore any matches it finds within <script> blocks AND
// it will also ignore the matches where the link includes a javascript command like
// <a href="javascript:alert{'& & &'}">blaw</a>
html = Regex.Replace(html, "&(?!(?<=(?<outerquote>[\"'])javascript:(?>(?!\\k<outerquote>|[>]).)*)\\k<outerquote>?)(?!(?:[a-zA-Z][a-zA-Z0-9]*|#\\d+);)(?!(?>(?:(?!<script|\\/script>).)*)\\/script>)", "&amp;", RegexOptions.Singleline | RegexOptions.IgnoreCase);

-1

该链接提供了一个很好的示例,说明何时以及为什么您可能需要转义&&amp;

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

有趣的是,我不得不对字符进行转义,以便在此处的答案中正确表示它。如果要使用内置的代码示例选项(从答案面板),我可以直接输入&amp;并按原样显示。但是,如果要手动使用该<code></code>元素,则必须先转义才能正确表示它:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.