192

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

4

6 回答 6

280

我以前对这些方法感到非常头疼,我建议您避免使用的任何变体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

于 2009-07-18T19:10:43.040 回答
139

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

于 2009-03-02T15:03:07.027 回答
80

自从第一次被问到这个问题已经快 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.EscapeDataStringUriFormatException在超过 65,520 个字符的字符串上抛出 a ;WebUtility.UrlEncode才不是。(一个比您想象的更常见的问题,尤其是在处理 URL 编码的表单数据时。)
  • Uri.EscapeDataStringUriFormatException高代理字符上抛出一个;WebUtility.UrlEncode才不是。(这是 UTF-16 的东西,可能不太常见。)

出于 URL 编码的目的,字符属于 3 类之一: 未保留(在 URL 中是合法的);保留(合法但具有特殊含义,因此您可能需要对其进行编码);以及其他所有内容(必须始终进行编码)。

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

并且未保留的字符是字母数字和-._~

判决

Uri.EscapeDataString明确定义了它的使命:%-编码所有保留和非法字符。WebUtility.UrlEncode在定义和实现上都比较模糊。奇怪的是,它编码了一些保留字符,但没有编码其他字符(为什么是括号而不是括号??),更奇怪的是,它仍然编码了那个无辜的未保留~字符。

因此,我同意流行的建议 - 尽可能使用Uri.EscapeDataString,并理解保留字符/?将被编码。如果您需要处理可能较大的字符串,尤其是 URL 编码的表单内容,则需要退回到WebUtility.UrlEncode并接受它的怪癖,或者以其他方式解决该问题。


编辑:试图通过、和static 方法纠正上述Flurl中提到的所有怪癖。这些在核心包中(很小,不包括所有的 HTTP 内容),或者随意从源代码中删除它们。我欢迎您对这些提出任何意见/反馈。Url.EncodeUrl.EncodeIllegalCharactersUrl.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}");
于 2017-12-18T22:49:02.680 回答
30

请记住,您可能不应该使用其中任何一种方法。Microsoft 的Anti-Cross Site Scripting Library包括更符合标准且更安全的HttpUtility.UrlEncode替代品。HttpUtility.HtmlEncode作为奖励,您还可以获得一种JavaScriptEncode方法。

于 2009-03-02T20:56:49.080 回答
11

Server.UrlEncode() 用于提供与经典 ASP 的向后兼容性,

Server.UrlEncode(str);

相当于:

HttpUtility.UrlEncode(str, Response.ContentEncoding);
于 2009-03-02T15:11:36.850 回答
5

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

于 2009-03-02T15:05:51.933 回答