服务器。 UrlEncode 与 HttpUtility.UrlEncode

Server.UrlEncode 和 HttpUtility.UrlEncode 之间有区别吗?

155129 次浏览

HttpServerUtility.UrlEncode将在内部使用 HttpUtility.UrlEncode。没有特别的区别。Server.UrlEncode存在的原因是与经典 ASP 的兼容性。

同样,Server.UrlEncode()调用 HttpUtility.UrlEncode()

UrlEncode ()是为了提供经典 ASP 的向下兼容,

Server.UrlEncode(str);

相当于:

HttpUtility.UrlEncode(str, Response.ContentEncoding);

请记住,您可能不应该使用这两种方法中的任何一种。微软的 反跨站脚本库包括 HttpUtility.UrlEncodeHttpUtility.HtmlEncode的替代品,它们都更符合标准,也更安全。作为奖励,您还得到了一个 JavaScriptEncode方法。

我以前对这些方法有很大的头痛,我建议您避免使用 ABC0的任何变体,而是使用“ a href = “ http://msdn.microsoft.com/en-us/library/system.uri.escape edatastring.aspx”rel = “ noReferrer”> 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

但是我个人最喜欢的还是 实用程序,UrlPathEncode——这个东西真的很难理解,它编码:

  • “% 20”= = > “% 20”
  • “100% 真实”= = > “100%% 20true”(好吧,你的网址现在被破坏了)
  • “ test A.aspx # 锚 B”= = > “ test% 20A. aspx# 锚% 20B
  • “ test A.aspx? hm # AnchorB”= = > “ test% 20A.aspx? hmm# 锚 B”(注意与前面的转义序列的不同!)

它还具有可爱的特定 MSDN 文档“对 URL 字符串的路径部分进行编码,以便从 Web 服务器向客户端进行可靠的 HTTP 传输。”没有解释它的作用。你不太可能用乌兹冲锋枪射自己的脚。

简而言之,坚持 < a href = “ http://msdn.microsoft.com/en-us/library/system.Uri.escape edatastring.aspx”rel = “ noReferrer”> Uri. EscapeDataString

从第一次被问到这个问题到现在快进了将近9年。NET 核心及。NET 标准,似乎我们对 URL 编码最常见的选项是 WebUtility.UrlEncode(在 System.Net下)和 Uri EscapeDataString。从这里和其他地方最流行的答案来看,Uri EscapeDataString似乎更可取。是吗?我做了一些分析以了解其中的差异,得出的结论如下:

  • WebUtility.UrlEncode将空间编码为 +; Uri.EscapeDataString将空间编码为 %20
  • 百分比编码 !()*; WebUtility.UrlEncode不编码。
  • 百分比编码 ~; Uri.EscapeDataString不编码。
  • 对于长于65,520个字符的字符串,Uri.EscapeDataString抛出 UriFormatException,而 WebUtility.UrlEncode不抛出 UriFormatException
  • Uri.EscapeDataString高级代理人角色上抛出一个 UriFormatException,而 WebUtility.UrlEncode不抛出(这是 UTF-16的东西,可能不太常见)

出于 URL 编码的目的,字符可以分为三类: 无保留(URL 中的合法字符) ; 保留(URL 中的合法字符,但有特殊含义,因此 也许吧希望对其进行编码) ; 以及其他所有字符(必须始终进行编码)。

根据 RFC,保留字符是: :/?#[]@!$&'()*+,;=

无保留字符是字母数字和 -._~

裁决

Uri EscapeDataString清楚地定义了它的使命:%-编码所有保留和非法字符。WebUtility.UrlEncode在定义和实现上更加模棱两可。奇怪的是,它编码一些保留字符而不是其他字符(为什么是括号而不是括号? ?)更奇怪的是,它编码的无辜无保留的 ~字符。

因此,我同意流行的建议——尽可能使用 Uri EscapeDataString,并理解保留字符,如 /?将得到编码。如果您需要处理潜在的大字符串,特别是 URL 编码的表单内容,那么您需要回到 WebUtility.UrlEncode并接受它的特点,或者以其他方式解决这个问题。


我已经通过 Url.EncodeUrl.EncodeIllegalCharactersUrl.Decode静态方法来纠正 扑扑中提到的所有怪癖。这些都在 核心软件包中(它很小,而且没有包含所有的 HTTP 内容) ,或者可以从源代码中删除它们。我欢迎你们对这些问题提出任何意见或反馈。


下面是我用来发现哪些字符编码不同的代码:

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}");