【问题标题】:Do I really need to encode '&' as '&'?我真的需要将'&'编码为'&'吗?
【发布时间】:2011-03-30 10:26:13
【问题描述】:

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

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

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

我真的需要&吗?

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

【问题讨论】:

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

标签: validation html utf-8 character-encoding


【解决方案1】:

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

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

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

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

【讨论】:

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

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

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

比较以下:哪个更容易?哪个更容易搞砸

方法 1

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

方法 2

(请加一点盐;))

  1. 写一些包含 & 字符的内容。
  2. 根据具体情况,查看每个 & 符号。确定是否:
  • 它是孤立的,因此毫无疑问是一个&符号。例如。 volt & amp
     > 在这种情况下,不要费心对其进行编码。
  • 它不是孤立的,但您仍然觉得它是明确的,因为生成的实体不存在并且永远不会存在,因为实体列表永远不会演变。例如,amp&volt
     >。在这种情况下,不要费心对其进行编码。
  • 它不是孤立的,也不是模棱两可的。例如,volt&amp
     > 对其进行编码。

??

【讨论】:

【解决方案3】:

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

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

【讨论】:

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

我认为这更多地变成了一个问题,即“为什么在浏览器不关心的情况下遵循规范”。这是我的笼统回答:

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

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

【讨论】:

  • 话虽如此,一般来说,您必须记住,大多数“标准”方式仍处于草稿模式,未来可能会发生变化。
【解决方案5】:

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

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

【讨论】:

    【解决方案6】:

    你能告诉我们你的title实际上是什么吗?当我提交时

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

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

    【讨论】:

    • 是的,HTML5 的解析器与以前的 HTML 和 XHTML 解析器不同,并且在某些情况下允许使用未转义的 & 符号。
    • 就这些示例而言,这在 HTML5 中并不是什么新鲜事。 &lt;title&gt;Dolce &amp; Gabbana&lt;/title&gt;&lt;p&gt;Dolce &amp; Gabbana&lt;/p&gt; 都是有效的 HTML 2.0。
    【解决方案7】:

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

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

    <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 总是使用像字符引用&amp;#38; 或实体引用&amp;amp; 这样的引用以避免混淆:

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

    【讨论】:

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

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

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

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

    【讨论】:

      【解决方案9】:

      如果用户将它传递给你,或者它会在一个 URL 中结束,你需要转义它。

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

      【讨论】:

        【解决方案10】:

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

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

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

        在文档中找到实体引用,但没有 由该名称定义的引用。这通常是由拼写错误引起的 参考名称、未编码的 & 符号,或通过省略 尾随分号 (;)。此错误的最常见原因是 URL 中未编码的 & 符号,如 WDG 在“Ampersands in URLs"。实体引用以 & 符号 (&) 开头,以 分号 (;)。如果您想在文档中使用文字 & 符号 您必须将其编码为“&”(即使在 URL 中!)。小心结束 带有分号的实体引用或您的实体引用可能会得到 结合以下文本进行解释。也请记住 命名实体引用区分大小写; &Aelig;和 是不同的字符。如果此错误出现在某些标记中 由 PHP 的会话处理代码生成,本文有 您的问题的解释和解决方案。

        【讨论】:

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

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

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

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

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

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

        【讨论】:

          【解决方案12】:

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

          的标签
          <div style="..." ... style="...">
          

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

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

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

          【讨论】:

            【解决方案13】:

            如果在 HTML 中使用了&amp;,那么您应该转义它。

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

            如果你正在使用 document.write 那么你应该使用它,例如document.write(&lt;p&gt;this &amp;amp; that&lt;/p&gt;).

            【讨论】:

            【解决方案14】:

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

            <title>Foo & Bar</title>
            

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

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

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

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

            【讨论】:

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

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

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

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

            【讨论】:

              猜你喜欢
              • 2012-03-13
              • 2020-01-29
              • 2011-01-28
              • 1970-01-01
              • 2016-07-26
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多