簡體   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