Server.UrlEncode 与 HttpUtility.UrlEncode

发布于 2024-07-14 22:20:50 字数 55 浏览 8 评论 0 原文

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

Is there a difference between Server.UrlEncode and HttpUtility.UrlEncode?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

放我走吧 2024-07-21 22:20:50

我之前对这些方法感到非常头疼,我建议您避免任何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%正确”==> “100%%20true”(好吧,您的网址现在已损坏)
  • “test A.aspx#anchor B”==> "test%20A.aspx#anchor%20B"
  • "test A.aspx?hmm#anchor B" ==> “test%20A.aspx?hmm#anchor B”(注意与之前的转义序列的区别!

它还有可爱的特定 MSDN 文档“对路径部分进行编码”用于从 Web 服务器到客户端进行可靠 HTTP 传输的 URL 字符串。” - 没有实际解释它的作用。 你不太可能用乌兹冲锋枪搬起石头砸自己的脚……

简而言之,坚持Uri.EscapeDataString

I had significant headaches with these methods before, I recommend you avoid any variant of UrlEncode, and instead use Uri.EscapeDataString - at least that one has a comprehensible behavior.

Let's see...

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

But my personal favorite has got to be HttpUtility.UrlPathEncode - this thing is really incomprehensible. It encodes:

  • " " ==> "%20"
  • "100% true" ==> "100%%20true" (ok, your url is broken now)
  • "test A.aspx#anchor B" ==> "test%20A.aspx#anchor%20B"
  • "test A.aspx?hmm#anchor B" ==> "test%20A.aspx?hmm#anchor B" (note the difference with the previous escape sequence!)

It also has the lovelily specific MSDN documentation "Encodes the path portion of a URL string for reliable HTTP transmission from the Web server to a client." - without actually explaining what it does. You are less likely to shoot yourself in the foot with an Uzi...

In short, stick to Uri.EscapeDataString.

满栀 2024-07-21 22:20:50

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

HttpServerUtility.UrlEncode will use HttpUtility.UrlEncode internally. There is no specific difference. The reason for existence of Server.UrlEncode is compatibility with classic ASP.

土豪我们做朋友吧 2024-07-21 22:20:50

自第一次提出这个问题以来已经快进近 9 年了,在 .NET Core 和 .NET Standard 的世界中,我们最常见的 URL 编码选项似乎是 WebUtility.UrlEncode (在System.Net)和Uri.EscapeDataString。 从这里和其他地方最流行的答案来看,Uri.EscapeDataString似乎更可取。 但真的是这样吗? 我做了一些分析来理解这些差异,这就是我得出的结论:

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

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

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

结论

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

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


编辑:我已经尝试纠正所有怪癖上面在 Flurl 中通过 Url.EncodeUrl.EncodeIllegalCharacters 提到和 Url.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}");

Fast-forward almost 9 years since this was first asked, and in the world of .NET Core and .NET Standard, it seems the most common options we have for URL-encoding are WebUtility.UrlEncode (under System.Net) and Uri.EscapeDataString. Judging by the most popular answer here and elsewhere, Uri.EscapeDataString appears to be preferable. But is it? I did some analysis to understand the differences and here's what I came up with:

  • WebUtility.UrlEncode encodes space as +; Uri.EscapeDataString encodes it as %20.
  • Uri.EscapeDataString percent-encodes !, (, ), and *; WebUtility.UrlEncode does not.
  • WebUtility.UrlEncode percent-encodes ~; Uri.EscapeDataString does not.
  • Uri.EscapeDataString throws a UriFormatException on strings longer than 65,520 characters; WebUtility.UrlEncode does not. (A more common problem than you might think, particularly when dealing with URL-encoded form data.)
  • Uri.EscapeDataString throws a UriFormatException on the high surrogate characters; WebUtility.UrlEncode does not. (That's a UTF-16 thing, probably a lot less common.)

For URL-encoding purposes, characters fit into one of 3 categories: unreserved (legal in a URL); reserved (legal in but has special meaning, so you might want to encode it); and everything else (must always be encoded).

According to the RFC, the reserved characters are: :/?#[]@!$&'()*+,;=

And the unreserved characters are alphanumeric and -._~

The Verdict

Uri.EscapeDataString clearly defines its mission: %-encode all reserved and illegal characters. WebUtility.UrlEncode is more ambiguous in both definition and implementation. Oddly, it encodes some reserved characters but not others (why parentheses and not brackets??), and stranger still it encodes that innocently unreserved ~ character.

Therefore, I concur with the popular advice - use Uri.EscapeDataString when possible, and understand that reserved characters like / and ? will get encoded. If you need to deal with potentially large strings, particularly with URL-encoded form content, you'll need to either fall back on WebUtility.UrlEncode and accept its quirks, or otherwise work around the problem.


EDIT: I've attempted to rectify ALL of the quirks mentioned above in Flurl via the Url.Encode, Url.EncodeIllegalCharacters, and Url.Decode static methods. These are in the core package (which is tiny and doesn't include all the HTTP stuff), or feel free to rip them from the source. I welcome any comments/feedback you have on these.


Here's the code I used to discover which characters are encoded differently:

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(
quot;{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");
眼泪也成诗 2024-07-21 22:20:50

请记住,您可能不应该使用其中任何一种方法。 Microsoft 的 反跨站脚本库 包括 < code>HttpUtility.UrlEncode 和 HttpUtility.HtmlEncode 都更符合标准,也更安全。 作为奖励,您还可以获得一个 JavaScriptEncode 方法。

Keep in mind that you probably shouldn't be using either one of those methods. Microsoft's Anti-Cross Site Scripting Library includes replacements for HttpUtility.UrlEncode and HttpUtility.HtmlEncode that are both more standards-compliant, and more secure. As a bonus, you get a JavaScriptEncode method as well.

﹏半生如梦愿梦如真 2024-07-21 22:20:50

Server.UrlEncode() 是为了提供与经典 ASP 的向后兼容性,

Server.UrlEncode(str);

相当于:

HttpUtility.UrlEncode(str, Response.ContentEncoding);

Server.UrlEncode() is there to provide backward compatibility with Classic ASP,

Server.UrlEncode(str);

Is equivalent to:

HttpUtility.UrlEncode(str, Response.ContentEncoding);
野鹿林 2024-07-21 22:20:50

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

The same, Server.UrlEncode() calls HttpUtility.UrlEncode()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文