除了&符号之外,HTML href/src属性中还应编码哪些字符?

6

请问在 HTML 属性中只有 & 这个符号需要编码吗?

众所周知,下面这段代码无法通过验证:

<a href="http://domain.com/search?q=whatever&lang=en"></a>

因为&符号应该是&amp;。这是一个直接链接到验证错误的网址。 这个人列出了许多需要编码的字符,但他是错的。如果你将http://中的第一个“/”进行编码,则href将无法正常工作。
在ASP.NET中,是否已经内置了处理此问题的帮助程序方法?像Server.UrlEncode和HtmlEncode这样的东西显然不起作用-它们是为不同的目的而设计的。
我可以构建自己的简单扩展方法(例如.ToAttributeView()),它只需进行简单的字符串替换即可。

1
URL编码不适用于整个URL。而&amp;是一个HTML实体,而不是URL编码的字符串。你似乎把这两个搞混了。 - BoltClock
1
不,我知道那是实体引用。这就是我的观点 - 还有哪些字符被编码了呢?如果在URL路径中有一个空格怎么办?我正在寻找关于此的权威指南。大多数参考指南似乎没有很好地涵盖这一点。他们只谈论总体URL编码。 - sohtimsso1970
2
@Felix 如果您在属性中留下裸的和号,所有HTML验证器都会发出警告。HTML常见错误 - sohtimsso1970
是的,没错,似乎是这样的... - Felix Kling
@Alohci - 哲学问题:谁来验证验证器?验证器和其他应用程序一样,也不免出现错误。 - c-smile
显示剩余4条评论
5个回答

9
除了对值进行标准的URI编码外,&符号是与HTML实体相关的唯一字符,你需要关注它,因为它是每个HTML实体的开头字符。以以下URL为例:
http://query.com/?q=foo&lt=bar&gt=baz

即使没有尾随的分号,因为 &lt; 是 < 的实体,&gt;是>的实体,一些旧浏览器仍会将此URL转换为:
http://query.com/?q=foo<=bar>=baz

所以,为了防止在HTML解析文档中出现这种情况,您需要将&指定为&amp;来处理链接。

1
转义字符的目的是为了防止它们被处理为参数。因此,您实际上不想对整个URL进行编码,只需对通过查询字符串传递的值进行编码即可。例如:
http://example.com/?parameter1=<ENCODED VALUE>&parameter2=<ENCODED VALUE>

你展示的URL实际上是一个完全有效的URL,可以通过验证。然而,浏览器会将&符号解释为查询字符串中参数之间的分隔符。因此,你的查询字符串:

?q=whatever&lang=en

实际上将被接收者翻译为两个参数:

q = "whatever"
lang = "en"

为了使您的URL正常工作,您只需要确保您的值已被编码:

?q=<ENCODED VALUE>&lang=<ENCODED VALUE>
编辑:你提供的 W3C 的常见问题页面是在讨论当 URL 在 HTML 中呈现时出现边缘情况的问题,例如 &copy 这样的实体引用。这里有一个在 jsfiddle 上展示该 URL 的测试链接:

http://jsfiddle.net/YjPHA/1/

在Chrome和FireFox中,链接正常工作,但IE将&copy呈现为©,从而破坏了链接。我必须承认,在实际应用中,我从未遇到过这个问题(它只会影响那些不需要分号的实体引用,这是一个非常小的子集)。
为确保您免受此错误的影响,您可以对呈现到页面上的任何URL进行HTML编码,这样就可以解决问题了。如果您正在使用ASP.NET,则HttpUtility.HtmlEncode方法应该可以很好地解决问题。

谢谢你的回复,Chris,但我不认为那是正确的。许多 来源 指出所有的和号都应该在HTML中进行编码。如果您不对它们进行编码,W3C验证器本身将无法验证您的内容。 - sohtimsso1970

1

1
嗯 - 是的,我明白你的观点。虽然解析错误与有效性错误不同,但我在HTML5规范中找不到任何迹象表明你提供的示例是无效的。HTML5规范(非规范性地)说:<a href="?bill&ted">Bill and Ted</a> <!-- &ted is ok, since it's not a named character reference -->,但validator.nu将其标记为错误。如果你还没有这样做,我认为你应该在validator.nu上报告此问题。 - Alohci

1
在 HTML 属性值中,如果您想要“,'&' 和非断行空格 ”作为结果,则应(作为明确意图的作者)在标记中使用&quot;,&amp; 和&nbsp;。
但是对于“,如果您使用单引号来包括属性值,则不必使用&quot;。
对于 HTML 文本节点,除上述外,如果您想要 < 和> 作为结果,则应使用&lt; 和&gt;。(我甚至在属性值中也会使用这些。)
对于 URI 的 hfnames 和 hfvalues(以及路径中的目录名称),我会使用 JavaScript 的 encodeURIComponent()(在 utf-8 页面上编码以在 utf-8 页面上使用)。

0

如果我理解问题正确,我相信this就是你想要的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接