我是否可以在<ahref…>中对与符号进行编码?


157

我正在编写自动生成HTML的代码,并且希望它正确编码。

假设我正在生成指向以下URL的链接:

http://www.google.com/search?rls=en&q=stack+overflow

我假设所有属性值都应进行HTML编码。(如果我写错了,请纠正我。)因此,这意味着如果将上述URL放入锚标记中,则应将&编码为&amp;,如下所示:

<a href="http://www.google.com/search?rls=en&amp;q=stack+overflow">

那是对的吗?



6
@CiroSantilli:关于实际的URL字符串;这是关于它们在HTML属性中出现时的编码方式。
JW。

如我所见,在html5中并不总是需要对&符号进行编码,并且答案已经过时了。
qdinar

Answers:


175

是的。HTML实体在HTML属性内部进行解析,并且流浪&会造成歧义。这就是为什么您应该始终编写&amp;而不是仅&所有 HTML属性内部编写的原因。

就是说,只需要&引号进行编码。如果属性中有特殊字符,则无需编码即可满足HTML解析器的要求。é

过去,URL需要使用非ASCII字符(例如)进行特殊处理é。您必须使用百分号转义编码,在这种情况下,它会给出%C3%A9,因为它们是由RFC 1738定义的。但是,RFC 1738已被RFC 3986(URI,统一资源标识符)和RFC 3987(IRI,国际化资源标识符)取代,WhatWG以此为基础来定义浏览器在看到具有非ASCII的URL时的行为。自HTML5以来的字符。因此,现在可以安全地在URL中包含非ASCII字符,无论是否经过百分比编码。


1
我对此非常确定,但是我有一个难得的疑问时刻。感谢您的确认。
JW。

1
您还可以将空格编码为“ +”而不是%20-这使URL易于阅读。
NickG 2013年

1
目前,在本机iPhone邮件客户端的mailto链接中,+不被尊重。
瑞安·奥尔森


4
我要补充一下(因为我刚刚陷入这个错误),如果您依赖模板引擎,则应该检查它是否自动处理转义HTML实体。在我的情况下,Twig正在这样做,而且我错误地两次转义写入&amp;tag属性,而不是直接使用&
Kamafeather 2015年

24

根据当前的官方HTML建议,必须在例如&amp;此类情况下对与号进行转义。但是,浏览器不需要它,因此HTML5 CR建议将此规则设为,以便将特殊规则应用于属性值。在这方面,当前的HTML5验证器已经过时了(请参见带有注释的错误报告)。

仍然可以转义属性值中的“&”号,但除了使用当前工具进行验证外,实际上没有必要将其转义为href值(如果您开始转义它们,则存在犯错误的小风险)。


4
不过,XHTML(发送为的实际 XHTML application/xhtml+xml)很可能总是需要它。
zneak 2013年

4
一个需要注意这一变化,目前仍在讨论,辩论,和误解,是,&是现在应该是好的,只要它是“ 联合国暧昧”。使“&”符号变得模棱两可的一种明显方法是,首先使用非空格字符,然后使用分号。该&符现在是模棱两可的,并且导致解析错误。
2015年

正如Jukka所说,对所有“&”号进行编码肯定存在风险,因此请考虑您的href网址之一包含分号的可能性。不太可能,因为我不确定我是否见过带有分号的网址。不是说它不能完成。因此,实际上,我认为我们的使用不太可能&会模棱两可。因此,我们将继续使用未经编码的href属性。
2015年

逃避是必要的全部原因恰恰是因为存在歧义的可能性。这个特定问题可能不是在99.99%的时间中都引入XSS攻击向量,渲染效果不好或没有任何影响,但这不是不打扰的原因。正确地进行转义非常困难,并且总是存在犯错误的可能性。
菲尔(Phil)

5

我发布了一个新答案,因为我发现zneak的答案没有足够的示例,没有将HTML和URI处理显示为不同的方面和标准,并且缺少一些小东西。

您有两个关于链接(<a href)中URL的标准。

第一个标准是RFC 1866(HTML 2.0),其中在“ 3.2.1。数据字符”中,您可以读取用作HTML属性值时需要转义的字符。(属性本身根本不允许使用特殊字符,例如<a hr&ef="http://...,不允许,也不允许<a hr&amp;ef="http://...。)

后来这已进入HTML 4标准,您需要转义的字符为:

<   to   &lt;
>   to   &gt;
&   to   &amp;
"   to   &quote;
'   to   &apos;

另一个标准是RFC 3986 “通用URI标准”,在该标准中处理URL(这种情况发生在浏览器要跟随链接,因为用户单击HTML元素时)。

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

对这些字符进行转义很重要,以便客户端知道它们是否代表数据或定界符。

未转义的示例:

https://example.com/?user=test&password&te&st&goto=https://google.com

示例,完整合法的URL

https://example.com/?user=test&password&te%26st&goto=https%3A%2F%2Fgoogle.com

HTML属性值中的示例完全合法的URL:

https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com

同样重要的场景:

  • JavaScript作为值:

    <img src="..." onclick="window.location.href = &quot;https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com&quot;;">...</a>(是的,;;是正确的。)

  • JSON作为值:

    <a href="..." data-analytics="{&quot;event&quot;: &quot;click&quot;}">...</a>

  • 转义内容中的转义内容,双重编码,参数内URL中的URL等,...

    http://x.com/?passwordUrl=http%3A%2F%2Fy.com%2F%3Fuser%3Dtest&amp;password=&quot;&quot;123


3

是的,你应该转换&&amp;

W3C的这个html验证器工具对于此类问题很有帮助。它将告诉您特定页面的错误和警告。


1
我不确定W3C验证程序是否将此&错误(在href中未转义)检测为错误。
ChrisW

6
当前,W3C验证器接受未转义的&为有效。这是否意味着标准已更改且不再需要编码?(在此做出大多数答案已过时)?如果是这样,这仅适用于href或任何属性吗?
matteo
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.