繁体   English   中英

Server.UrlEncode与HttpUtility.UrlEncode

[英]Server.UrlEncode vs. HttpUtility.UrlEncode

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

我之前对这些方法感到非常头痛, 我建议你避免使用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”(好吧,你的网址现在坏了)
  • “test A.aspx#anchor B”==>“test%20A.aspx #anchor%20B
  • “测试A.aspx?hmm#anchor B”==>“test%20A.aspx?hmm #anchor B ”( 注意与前一个转义序列的区别!

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

简而言之,坚持使用Uri.EscapeDataString

HttpServerUtility.UrlEncodeHttpUtility.UrlEncode内部使用HttpUtility.UrlEncode 没有具体的区别。 Server.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个字符长; WebUtility.UrlEncode没有。 比您想象的更常见的问题,特别是在处理URL编码的表单数据时 。)
  • Uri.EscapeDataString高代理字符抛出UriFormatException ; WebUtility.UrlEncode没有。 (这是一个UTF-16的东西,可能不太常见。)

对于URL编码目的,字符符合以下三个类别之一:未保留(URL中合法); 保留(合法但具有特殊含义,因此您可能希望对其进行编码); 和其他一切(必须始终编码)。

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

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

判决

Uri.EscapeDataString明确定义了它的任务:% - 编码所有保留和非法字符。 WebUtility.UrlEncode在定义和实现方面都更加模糊。 奇怪的是,它编码的一些保留字符而不是其他(为什么括号,而不是括号?),并且奇怪的是它编码傻傻未保留~字符。

因此,我同意流行的建议 - 尽可能使用Uri.EscapeDataString ,并了解保留字符,如/? 将被编码。 如果你需要处理潜在的大字符串,特别是URL编码的表单内容,你需要依靠WebUtility.UrlEncode并接受它的怪癖,或以其他方式解决问题。


编辑:试图通过Url.EncodeUrl.EncodeIllegalCharactersUrl.Decode静态方法纠正Flurl中上面提到的所有怪癖。 这些是在核心包中 (它很小,并不包括所有的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}");

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

Server.UrlEncode()用于向后兼容Classic ASP,

Server.UrlEncode(str);

相当于:

HttpUtility.UrlEncode(str, Response.ContentEncoding);

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM