Server.UrlEncode проти HttpUtility.UrlEncode


Відповіді:


133

HttpServerUtility.UrlEncodeбуде використовувати HttpUtility.UrlEncodeвнутрішньо. Конкретної різниці немає. Причиною існування Server.UrlEncodeє сумісність із класичним ASP.


3
Щодо того, що втече. Внутрішньо він називає цю функцію referenceource.microsoft.com/#System/net/System/Net/…
Jeff

Для читачів: Будь ласка, подивіться на відповідь Джоеля Мюллера нижче. Це найбільш ефективний спосіб URL кодування: stackoverflow.com/a/603962/190476
Sudhanshu Мішра

264

Раніше у мене були сильні головні болі з цими методами, я рекомендую вам уникати будь-яких варіантів 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" (нормально, ваша URL-адреса порушена)
  • "тест A.aspx # якір B" ==> "тест% 20A.aspx # якір% 20B "
  • "test A.aspx? hmm # anchor B" ==> "test% 20A.aspx? hmm #anchor B " ( зверніть увагу на різницю з попередньою послідовністю втечі! )

У ньому також є кохана специфічна документація MSDN "Кодує частину шляху URL-рядка для надійної передачі HTTP від ​​веб-сервера до клієнта." - не пояснюючи насправді, що робить. Ви рідше стріляєте собі в ногу узі ...

Словом, дотримуйтесь Uri.EscapeDataString .


4
І, на жаль, це все ще не працює при виконанні HTTP-запитів на деяких веб-серверах - Uri.EscapeDataString () не кодує "!" або "" ", що відрізняється від того, як працює більшість реалізацій браузера escape () ...
Кріс Р. Доннеллі,

6
! і 'символи не повинні кодуватися; але якщо цього вимагає помилковий веб-сервер, його легко вирішити. Уникайте функції втечі Javascript - вона по суті є баггі (неможливо обійти, для одного). Дивіться xkr.us/articles/javascript/encode-compare - але коротко; ви можете використовувати замість цього encodeUriComponent (), який поводиться аналогічно EscapeDataString - він передбачувано та зворотно кодує рядок, а також не кодує! і 'символи.
Еймон Нербонна

2
Це старе, але питання натрапило на головну сторінку, тому .... Частина шляху рядка URL - це частина між доменом і? або # в URL-адресі.
Powerlord

2
@Tim: може бути декілька, ?і хто може сказати, що потрібно закодувати, а які - роздільники? Щодо простору: в обох випадках простір знаходиться у хеші, тому наявність або відсутність запиту-фрагмента не має значення. І нарешті, недоцільно псувати Uri, як у другому прикладі, що містить%. UrlPathEncodeМетод рівнини BORKED і ніколи не повинен використовуватися.
Еймон Нербонна

1
Я думаю, що моя відповідь на сайті stackoverflow.com/a/13993486/237091 може пролити трохи світла щодо передбачуваного використання UrlEncode / UrlPathEncode.
Скотт Стаффорд

60

Перемотування вперед майже 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 і прийняти його химерності , або іншим чином вирішити проблему.


EDIT: Я намагався виправити все з примх , згаданих вище в Flurl через Url.Encode, Url.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}");

2
Це геніально!
Хорхе Агірре

1
Відмінна робота з перевірки запропонованого рішення в сучасних рамках .net.
Neowizard

Слід зазначити, що між WebUtility та HttpUtility є деякі відмінності . WebUtility використовує великі регістри, а HttpUtility використовує малі регістри для шістнадцяткових об'єктів. Крім того, HttpUtility не був включений у старі підмножинні версії .NET Framework "Профіль клієнта". WebUtility доступний у .NET Framework 4.0.
tibx

28

Майте на увазі, що ви, мабуть, не повинні використовувати жоден із цих методів. Від Microsoft Anti-Cross Site Scripting Library включає в себе заміну для HttpUtility.UrlEncodeі HttpUtility.HtmlEncodeщо обидва є більш відповідними стандартами, і більш безпечним. Як бонус, ви також отримуєте JavaScriptEncodeметод.


Прочитавши документацію та поширені запитання за наданим посиланням, я вважаю, що ця відповідь є найкращим і безпечним способом кодування даних! Дякую тонну за те, що поділилися цим!
Sudhanshu Mishra

Посилання вже не працює. Які методи заміни?
Едвард Брей

@EdwardBrey Це остання версія бібліотеки сценаріїв анти-кросів на сайті: microsoft.com/en-au/download/details.aspx?id=28589
Sudhanshu Mishra

11

Server.UrlEncode () є для забезпечення зворотної сумісності з Classic ASP,

Server.UrlEncode(str);

Еквівалентний:

HttpUtility.UrlEncode(str, Response.ContentEncoding);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.