EscapeUriString ve EscapeDataString arasındaki fark nedir?


195

Sadece url kodlaması ile ilgileniyorsanız, EscapeUriString kullanmalıyım ?


10
Her zaman her kaçış değerini kullanarak Uri.EscapeDataString()Livven cevabı @ açıklandığı gibi,. Diğer yaklaşımlarla sistem, olası her girdi için amaçlanan sonucu üretmek için yeterli bilgiye sahip değildir.
Timo

Yanıtlar:


112

EscapeDataStringHer zaman kullanın (neden hakkında daha fazla bilgi için aşağıdaki Livven'in cevabına bakın)

Düzenleme : iki kodlama farklı nasıl ölü bağlantı kaldırıldı


3
Esacaping yerine kaçış ile ilgili olarak bağlantı aslında daha fazla bilgi sağlar emin değilim.
Steven

1
Temelde aynı fark. Makaleyi gerçekten okuduysanız, ortada etrafında farklılıkları göstermek için kaçan (kaçan olmayan) bir tablo var (ile karşılaştırıldığında URLEncode).
Jcl

2
Benim için hala net değil - ya bütün bir URI'den değil, sadece bir kısmından kaçarsam - (yani bir sorgu dizesi parametresinin verileri )? URI için veri kaçıyor muyum, yoksa EscapeDataString tamamen farklı bir şey mi ima ediyor?
BrainSlugs83 10:13

4
... bir URI parametresi için EscapeDataString istiyorum gibi bazı testler yaptım. "I heart C ++" dizesiyle test ettim ve EscapeUriString "+" karakterlerini kodlamadı, sadece olduğu gibi bıraktı, EscapeDataString doğru şekilde "% 2B" 'ye dönüştürdü.
BrainSlugs83 10:13

7
Bu kötü bir cevap. Asla EscapeUriString kullanmamalısınız, hiç mantıklı değil. Aşağıdaki Livven'in cevabına bakın (ve oy verin).
Brandon Paddock

243

Mevcut cevapları tatmin edici bulamadım, bu yüzden bu sorunu çözmek için biraz daha derine inmeye karar verdim. Şaşırtıcı bir şekilde, cevap çok basit:

Kullanmak için geçerli bir neden yoktur (neredeyse *) Uri.EscapeUriString. Bir dizeyi yüzde olarak kodlamanız gerekiyorsa daima kullanın Uri.EscapeDataString.

* Geçerli bir kullanım durumu için son paragrafa bakınız.

Bu neden? Belgelere göre :

Uri yapıcısına parametre olarak çıkış karakteri olmayan bir URI dizesi hazırlamak için EscapeUriString yöntemini kullanın.

Bu gerçekten mantıklı değil. RFC 2396'ya göre :

Bir URI her zaman "kaçar" biçimindedir, çünkü tamamlanmış bir URI'den kaçmak veya kaçmak anlambilimini değiştirebilir.

Alıntılanan RFC, RFC 3986 tarafından kullanılmazken , nokta hala duruyor. Bazı somut örneklere bakarak bunu doğrulayalım:

  1. Bunun gibi basit bir URI'nız var:

    http://example.org/

    Uri.EscapeUriString değişmeyecek.

  2. Sorgu dizesini kaçmaya dikkat etmeden el ile düzenlemeye karar verdiniz:

    http://example.org/?key=two words

    Uri.EscapeUriString (doğru) sizin için alandan kaçacak:

    http://example.org/?key=two%20words
  3. Sorgu dizesini manuel olarak daha da düzenlemeye karar verdiniz:

    http://example.org/?parameter=father&son

    Ancak, bu dize değişmez Uri.EscapeUriString, çünkü işareti ve başka bir anahtar / değer çiftinin başlangıcını belirtir. İstediğiniz gibi olabilir veya olmayabilir.

  4. Aslında keyparametrenin olmasını istediğinize siz karar verirsiniz father&son, böylece önceki URL'yi "ve" işaretinden kaçarak manuel olarak düzeltirsiniz:

    http://example.org/?parameter=father%26son

    Ancak, Uri.EscapeUriStringyüzde karakterinden de kaçarak çift kodlamaya yol açar:

    http://example.org/?parameter=father%2526son

Gördüğünüz gibi Uri.EscapeUriString, amacına uygun olarak kullanmak &, bir sorgu dizesinde birden çok anahtar / değer çifti arasında ayırıcı yerine bir anahtarın veya değerin bir parçası olarak kullanılmasını imkansız hale getirir .

Bunun nedeni, tam URI'lerden kaçmak için uygun hale getirme girişiminde, ayrılmış karakterleri yok sayar ve yalnızca ne ayrılmış ne de kaydedilmemiş karakterlerden kaçar; BTW, belgelere aykırıdır . Bu şekilde http%3A%2F%2Fexample.org%2F, bunun gibi bir şeyle sonuçlanmazsınız , ancak yukarıda gösterilen sorunlarla sonuçlanırsınız.


Sonunda, URI'niz geçerliyse, Uri yapıcısına bir parametre olarak geçirilmek için kaçmasına gerek yoktur ve geçerli Uri.EscapeUriStringdeğilse, arama da sihirli bir çözüm değildir. Aslında, çoğu durumda olmasa da birçok durumda çalışacaktır, ancak hiçbir şekilde güvenilir değildir.

URL'lerinizi ve sorgu dizelerinizi her zaman anahtar / değer çiftlerini ve yüzde kodlamasını toplayıp ardından gerekli ayırıcılarla birleştirerek oluşturmalısınız. Uri.EscapeDataStringBu amaçla kullanabilirsiniz , ancak kullanamazsınız Uri.EscapeUriString, çünkü yukarıda belirtildiği gibi ayrılmış karakterlerden kaçmaz.

Sadece bunu yapamazsanız, örneğin kullanıcı tarafından sağlanan URI'lerle uğraşırken, Uri.EscapeUriStringson çare olarak kullanmak mantıklıdır . Ancak daha önce belirtilen uyarılar geçerlidir - kullanıcı tarafından sağlanan URI belirsizse, sonuçlar istenmeyebilir.


4
Vay canına, nihayet bu sorunu açıkladığınız için teşekkür ederim. Önceki iki cevap çok yardımcı olmadı.
EverPresent

3
Kesinlikle doğru. EscapeUriString (EscapeUrl'ın Win32'deki varsayılan davranışı gibi) URI'leri anlamayan veya kaçan biri tarafından oluşturuldu. Yanlış biçimlendirilmiş bir URI alan ve bazen onu istenen sürüme dönüştüren yanlış yönlendirilmiş bir girişimdir . Ancak bunu güvenilir bir şekilde yapmak için ihtiyaç duyduğu bilgiye sahip değil. Ayrıca çok sorunlu olan EscapeDataString yerine sıklıkla kullanılır. Keşke EscapeUriString olmasaydı. Her kullanımı yanlış.
Brandon Paddock

4
güzel açıkladı +1 kabul bağlantı sadece cevap daha iyidir
Ehsan Sajjad

1
Bu cevabın daha fazla dikkat edilmesi gerekiyor. Bunu yapmanın doğru yolu. Diğer cevaplar, amaçlanan sonuçları üretmedikleri senaryolara sahiptir.
Timo

1
... Tabii encodeURI/ Uri.EscapeUriStringolarak gerekli değildir sıklıkta encodeURIComponent/ Uri.EscapeDataString(bir uri bağlamda kullanılması gerekir kör adresler ile deaing olduğunda bu yana), ancak anlamına gelmez onun yeri yok.
Crescent Fresh

56

Artı (+) karakterler, bu yöntemler arasındaki fark hakkında çok şey ortaya çıkarabilir. Basit bir URI'de, artı karakteri "boşluk" anlamına gelir. Google'ı "mutlu kedi" için sorgulamayı düşünün:

https://www.google.com/?q=happy+cat

Bu geçerli bir URI (deneyin) ve EscapeUriStringdeğiştirmez.

Şimdi Google'ı "happy c ++" için sorgulamayı düşünün:

https://www.google.com/?q=happy+c++

Bu geçerli bir URI (deneyin), ancak "mutlu c" için bir arama üretir, çünkü iki artı boşluk olarak yorumlanır. Düzeltmek için, "mutlu c ++" EscapeDataStringve voila * iletebiliriz :

https://www.google.com/?q=happy+c%2B%2B

*) Kodlanmış veri dizesi aslında "mutlu% 20c% 2B% 2B" dir; % 20 boşluk karakteri için onaltılı ve% 2B artı karakteri için onaltılı.

Eğer UriBuilderolması gerektiği gibi kullanıyorsanız , sadece EscapeDataStringtüm URI'nizin bazı bileşenlerinden düzgün bir şekilde kaçmanız gerekir . @ Livven'in bu soruya vereceği cevap, kullanmak için gerçekten bir neden olmadığını kanıtlıyor EscapeUriString.


Teşekkürler. Eğer örneğin, kodlamak için gereken bir mutlak URI dizesini olduğunda ne olacak "https://www.google.com/?q=happy c++". Görünüşe göre el ile "?" Üzerine bölmek gerekir, ya da daha iyi bir yolu var mı?
wensveen

URL'nin tamamını başka bir URL'ye parametre olarak geçiriyorsanız, kullanın EscapeDataString. Girdiğiniz URL gerçek URL ise, evet sadece ayrılmak istersiniz ?.
Seth

7

Kaynaktaki yorumlar farkı açıkça ele alır. Bu bilgilerin neden XML dokümantasyon yorumları yoluyla sunulmaması benim için bir sırdır.

EscapeUriString:

Bu yöntem, yüzde işaretleri dahil olmak üzere ayrılmış veya kaydedilmemiş bir karakter olmayan herhangi bir karakterden kaçacaktır. EscapeUriString'in '#' işaretinden de kaçmayacağını unutmayın.

EscapeDataString:

Bu yöntem, yüzde işaretleri de dahil olmak üzere, kaydedilmemiş bir karakter olmayan herhangi bir karakterden kaçacaktır.

Fark, ayrılmış karakterleri nasıl ele aldıklarıdır . EscapeDataStringonlardan kaçar; EscapeUriStringdeğil.

RFC'ye göre , ayrılmış karakterler::/?#[]@!$&'()*+,;=

Tamlık için, kaydedilmemiş karakterler alfasayısaldır ve -._~

Her iki yöntem de rezerve edilmemiş veya edilmemiş karakterlerden kaçar.

Ben genel katılmıyorum kavramınaEscapeUriString kötülüktür. Ben sadece yasadışı karakterler (boşluk gibi) kaçan ve ayrılmış değil karakterler bir yöntem yararlı olduğunu düşünüyorum. Ancak %karakteri nasıl ele aldığı konusunda tuhaftır . Yüzde kodlu karakterler ( %ardından 2 onaltılık basamak), bir URI'de yasaldır . EscapeUriStringBu modeli tespit ederse ve %hemen 2 onaltılık basamakla ilerlediğinde kodlamadan kaçınırsa çok daha yararlı olacağını düşünüyorum .


1

Basit bir örnek

var data = "example.com/abc?DEF=あいう\x20えお";

Console.WriteLine(Uri.EscapeUriString(data));
Console.WriteLine(Uri.EscapeDataString(data));
Console.WriteLine(System.Net.WebUtility.UrlEncode(data));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(data));

/*
=>
example.com/abc?DEF=%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86+%E3%81%88%E3%81%8A
example.com%2fabc%3fDEF%3d%e3%81%82%e3%81%84%e3%81%86+%e3%81%88%e3%81%8a
*/
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.