Jika hanya berurusan dengan penyandian url, saya harus menggunakan EscapeUriString ?
Jika hanya berurusan dengan penyandian url, saya harus menggunakan EscapeUriString ?
Jawaban:
Gunakan EscapeDataString
selalu (untuk info lebih lanjut tentang alasannya, lihat jawaban Livven di bawah)
Sunting : menghapus tautan mati ke bagaimana keduanya berbeda dalam pengodean
URLEncode
terlalu).
Saya tidak menemukan jawaban yang ada memuaskan, jadi saya memutuskan untuk menggali sedikit lebih dalam untuk menyelesaikan masalah ini. Anehnya, jawabannya sangat sederhana:
Ada (hampir *) tidak ada alasan valid untuk menggunakannya Uri.EscapeUriString
. Jika Anda perlu meng-enkode string, selalu gunakan Uri.EscapeDataString
.
* Lihat paragraf terakhir untuk kasus penggunaan yang valid.
Kenapa ini? Menurut dokumentasi :
Gunakan metode EscapeUriString untuk menyiapkan string URI yang tidak terhapus untuk menjadi parameter bagi konstruktor Uri.
Ini tidak masuk akal. Menurut RFC 2396 :
URI selalu dalam bentuk "melarikan diri", karena melarikan diri atau melepaskan URI yang lengkap dapat mengubah semantiknya.
Sementara RFC yang dikutip telah usang oleh RFC 3986 , intinya masih berdiri. Mari kita verifikasi dengan melihat beberapa contoh nyata:
Anda memiliki URI sederhana, seperti ini:
http://example.org/
Uri.EscapeUriString
tidak akan mengubahnya.
Anda memutuskan untuk mengedit string kueri secara manual tanpa mempertimbangkan untuk melarikan diri:
http://example.org/?key=two words
Uri.EscapeUriString
akan (dengan benar) keluar dari ruang untuk Anda:
http://example.org/?key=two%20words
Anda memutuskan untuk mengedit string kueri secara manual lebih jauh:
http://example.org/?parameter=father&son
Namun, string ini tidak diubah oleh Uri.EscapeUriString
, karena mengasumsikan ampersand menandakan dimulainya pasangan nilai kunci lainnya. Ini mungkin atau mungkin bukan apa yang Anda maksudkan.
Anda memutuskan bahwa Anda sebenarnya menginginkan key
parameternya father&son
, jadi Anda memperbaiki URL sebelumnya secara manual dengan keluar dari ampersand:
http://example.org/?parameter=father%26son
Namun, Uri.EscapeUriString
akan keluar dari karakter persen juga, yang mengarah ke pengkodean ganda:
http://example.org/?parameter=father%2526son
Seperti yang Anda lihat, menggunakan Uri.EscapeUriString
untuk tujuan yang dimaksudkan membuatnya tidak mungkin untuk digunakan &
sebagai bagian dari kunci atau nilai dalam string kueri alih-alih sebagai pemisah antara beberapa pasangan nilai kunci.
Ini karena, dalam upaya membuatnya cocok untuk keluar dari URI penuh, ia mengabaikan karakter yang dipesan dan hanya lolos karakter yang tidak dilindungi atau tidak dilindungi, yang, BTW, bertentangan dengan dokumentasi . Dengan cara ini Anda tidak berakhir dengan sesuatu seperti http%3A%2F%2Fexample.org%2F
, tetapi Anda berakhir dengan masalah yang digambarkan di atas.
Pada akhirnya, jika URI Anda valid, itu tidak perlu diloloskan untuk dilewatkan sebagai parameter ke konstruktor Uri, dan jika itu tidak valid maka menelepon Uri.EscapeUriString
juga bukan solusi ajaib. Sebenarnya, ini akan berfungsi dalam banyak kasus, jika tidak dalam banyak kasus, tetapi tidak dapat diandalkan.
Anda harus selalu membuat URL dan string kueri dengan mengumpulkan pasangan nilai kunci dan pengkodean persen lalu menggabungkannya dengan pemisah yang diperlukan. Anda dapat menggunakan Uri.EscapeDataString
untuk tujuan ini, tetapi tidakUri.EscapeUriString
, karena itu tidak luput dari karakter yang dipesan, seperti yang disebutkan di atas.
Hanya jika Anda tidak dapat melakukan itu, misalnya ketika berhadapan dengan URI yang disediakan pengguna, apakah masuk akal untuk digunakan Uri.EscapeUriString
sebagai upaya terakhir. Tetapi peringatan yang disebutkan sebelumnya berlaku - jika URI yang diberikan pengguna ambigu, hasilnya mungkin tidak diinginkan.
encodeURI
/ Uri.EscapeUriString
tidak diperlukan sesering encodeURIComponent
/ Uri.EscapeDataString
(karena kapan Anda deaing dengan url buta yang harus digunakan dalam konteks uri), tetapi itu tidak berarti itu tidak memiliki tempatnya.
Karakter plus (+) dapat mengungkapkan banyak tentang perbedaan antara metode ini. Dalam URI sederhana, karakter plus berarti "ruang". Pertimbangkan meminta Google untuk "kucing bahagia":
Itu URI yang valid (coba), dan EscapeUriString
tidak akan memodifikasinya.
Sekarang pertimbangkan untuk meminta Google untuk "happy c ++":
Itu URI yang valid (coba saja), tetapi menghasilkan pencarian untuk "happy c", karena dua plus ditafsirkan sebagai spasi. Untuk memperbaikinya, kita dapat meneruskan "happy c ++" ke EscapeDataString
dan voila * :
*) String data yang disandikan sebenarnya "happy% 20c% 2B% 2B"; % 20 adalah hex untuk karakter spasi, dan% 2B adalah hex untuk karakter plus.
Jika Anda menggunakan UriBuilder
sebagaimana mestinya, maka Anda hanya perlu EscapeDataString
melarikan diri dengan benar beberapa komponen seluruh URI Anda. @ Livven menjawab pertanyaan ini lebih lanjut membuktikan bahwa tidak ada alasan untuk menggunakannya EscapeUriString
.
"https://www.google.com/?q=happy c++"
. Sepertinya saya perlu membelah secara manual pada "?", Atau apakah ada cara yang lebih baik?
EscapeDataString
. Jika URL yang Anda berikan adalah URL yang sebenarnya, maka ya Anda ingin membagi saja ?
.
Komentar di sumber mengatasi perbedaan dengan jelas. Mengapa info ini tidak diajukan melalui dokumentasi dokumentasi komentar adalah misteri bagi saya.
EscapeUriString:
Metode ini akan lolos dari karakter apa pun yang bukan karakter yang dilindungi atau tidak dilindungi, termasuk tanda persen. Perhatikan bahwa EscapeUriString juga tidak akan keluar dari tanda '#'.
EscapeDataString:
Metode ini akan lolos dari karakter apa pun yang bukan karakter tanpa syarat, termasuk tanda persen.
Jadi perbedaannya adalah bagaimana mereka menangani karakter yang dipesan . EscapeDataString
lolos dari mereka;EscapeUriString
tidak.
Menurut RFC , karakter yang dipesan adalah::/?#[]@!$&'()*+,;=
Untuk kelengkapan, karakter tanpa syarat adalah alfanumerik dan -._~
Kedua metode lolos karakter yang tidak dilindungi undang-undang atau tidak dilindungi.
Saya tidak setuju dengan anggapan umum bahwa EscapeUriString
itu jahat. Saya pikir metode yang lolos hanya karakter ilegal (seperti spasi) dan karakter tidak dilindungi undang - undang berguna. Tetapi memang memiliki kekhasan dalam bagaimana menangani %
karakter. Karakter yang dikodekan persen ( %
diikuti oleh 2 digit hex) adalah legal dalam URI. Saya pikir EscapeUriString
akan jauh lebih berguna jika mendeteksi pola ini dan menghindari pengkodean %
ketika segera diproses oleh 2 digit hex.
Contoh sederhana
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
*/
Uri.EscapeDataString()
, seperti yang dijelaskan dalam jawaban @ Livven. Dengan pendekatan lain, sistem tidak memiliki cukup informasi untuk menghasilkan hasil yang diinginkan untuk setiap input yang mungkin.