Server.UrlEncode 和 HttpUtility.UrlEncode 有区别吗?
6 回答
我以前对这些方法感到非常头疼,我建议您避免使用的任何变体UrlEncode
,而是使用Uri.EscapeDataString
- 至少该方法具有可理解的行为。
让我们来看看...
HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
//standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
// want, since you still need to
// escape special characters yourself
但我个人最喜欢的一定是HttpUtility.UrlPathEncode - 这东西真的是难以理解。它编码:
- " " ==> "%20"
- "100% true" ==> "100%%20true"(好的,你的网址现在坏了)
- "测试 A.aspx#anchor B" ==> "测试%20A.aspx #anchor%20B "
- "test A.aspx?hmm#anchor B" ==> "test%20A.aspx?hmm #anchor B "(注意与前面转义序列的区别!)
它还具有可爱的特定 MSDN 文档“对 URL 字符串的路径部分进行编码,以实现从 Web 服务器到客户端的可靠 HTTP 传输”。- 没有实际解释它的作用。你不太可能用 Uzi 开枪打自己的脚......
简而言之,坚持Uri.EscapeDataString。
HttpServerUtility.UrlEncode
将在HttpUtility.UrlEncode
内部使用。没有具体的区别。存在的原因Server.UrlEncode
是与经典的 ASP 兼容。
自从第一次被问到这个问题已经快 9 年了,在 .NET Core 和 .NET Standard 的世界中,我们对 URL 编码最常见的选项似乎是WebUtility.UrlEncode(在 下System.Net
)和Uri.EscapeDataString。从这里和其他地方最流行的答案来看,Uri.EscapeDataString似乎更可取。但是是吗?我做了一些分析以了解差异,这就是我想出的:
WebUtility.UrlEncode
将空间编码为+
;Uri.EscapeDataString
将其编码为%20
.Uri.EscapeDataString
百分比编码!
,(
,)
, 和*
;WebUtility.UrlEncode
才不是。WebUtility.UrlEncode
百分比编码~
;Uri.EscapeDataString
才不是。Uri.EscapeDataString
UriFormatException
在超过 65,520 个字符的字符串上抛出 a ;WebUtility.UrlEncode
才不是。(一个比您想象的更常见的问题,尤其是在处理 URL 编码的表单数据时。)Uri.EscapeDataString
UriFormatException
在高代理字符上抛出一个;WebUtility.UrlEncode
才不是。(这是 UTF-16 的东西,可能不太常见。)
出于 URL 编码的目的,字符属于 3 类之一: 未保留(在 URL 中是合法的);保留(合法但具有特殊含义,因此您可能需要对其进行编码);以及其他所有内容(必须始终进行编码)。
根据RFC,保留字符是::/?#[]@!$&'()*+,;=
并且未保留的字符是字母数字和-._~
判决
Uri.EscapeDataString明确定义了它的使命:%-编码所有保留和非法字符。WebUtility.UrlEncode在定义和实现上都比较模糊。奇怪的是,它编码了一些保留字符,但没有编码其他字符(为什么是括号而不是括号??),更奇怪的是,它仍然编码了那个无辜的未保留~
字符。
因此,我同意流行的建议 - 尽可能使用Uri.EscapeDataString,并理解保留字符/
和?
将被编码。如果您需要处理可能较大的字符串,尤其是 URL 编码的表单内容,则需要退回到WebUtility.UrlEncode并接受它的怪癖,或者以其他方式解决该问题。
编辑:我试图通过、和static 方法纠正上述Flurl中提到的所有怪癖。这些在核心包中(很小,不包括所有的 HTTP 内容),或者随意从源代码中删除它们。我欢迎您对这些提出任何意见/反馈。Url.Encode
Url.EncodeIllegalCharacters
Url.Decode
这是我用来发现哪些字符编码不同的代码:
var diffs =
from i in Enumerable.Range(0, char.MaxValue + 1)
let c = (char)i
where !char.IsHighSurrogate(c)
let diff = new {
Original = c,
UrlEncode = WebUtility.UrlEncode(c.ToString()),
EscapeDataString = Uri.EscapeDataString(c.ToString()),
}
where diff.UrlEncode != diff.EscapeDataString
select diff;
foreach (var diff in diffs)
Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");
请记住,您可能不应该使用其中任何一种方法。Microsoft 的Anti-Cross Site Scripting Library包括更符合标准且更安全的HttpUtility.UrlEncode
替代品。HttpUtility.HtmlEncode
作为奖励,您还可以获得一种JavaScriptEncode
方法。
Server.UrlEncode() 用于提供与经典 ASP 的向后兼容性,
Server.UrlEncode(str);
相当于:
HttpUtility.UrlEncode(str, Response.ContentEncoding);
同样,Server.UrlEncode()
调用HttpUtility.UrlEncode()