Katakanlah saya punya URL
http://example.com/query?q=
dan saya memiliki kueri yang dimasukkan oleh pengguna seperti:
kata acak £ 500 bank $
Saya ingin hasilnya menjadi URL yang disandikan dengan benar:
http://example.com/query?q=random%20word%20%A3500%20bank%20%24
Apa cara terbaik untuk mencapai ini? Saya mencoba URLEncoder
dan membuat objek URI / URL tetapi tidak satupun yang benar.
Jawaban:
URLEncoder
adalah cara untuk pergi. Anda hanya perlu mengingat untuk menyandikan hanya nama dan / atau nilai parameter string kueri individual, bukan keseluruhan URL, yang pasti bukan karakter pemisah parameter string kueri&
atau karakter pemisah nilai-nilai parameter=
.Perhatikan bahwa spasi dalam parameter kueri diwakili oleh
+
, bukan%20
, yang sah secara sah. The%20
biasanya digunakan untuk mewakili ruang di URI sendiri (bagian sebelum URI-string kueri karakter pemisah?
), tidak dalam query string (bagian setelah?
).Perhatikan juga bahwa ada tiga
encode()
metode. Satu tanpaCharset
sebagai argumen kedua dan lainnya denganString
sebagai argumen kedua yang melempar pengecualian diperiksa. Yang tanpaCharset
argumen sudah usang. Jangan pernah menggunakannya dan selalu tentukanCharset
argumennya. The javadoc bahkan secara eksplisit menganjurkan untuk menggunakan UTF-8 encoding, sebagaimana diamanatkan oleh RFC3986 dan W3C .Lihat juga:
sumber
URLEncoder
adalah untuk parameter kueri yang disandikan URL sesuaiapplication/x-www-form-urlencoded
aturan. Parameter jalur tidak cocok dalam kategori ini. Anda membutuhkan encoder URI sebagai gantinya.Saya tidak akan menggunakan
URLEncoder
. Selain salah nama (URLEncoder
tidak ada hubungannya dengan URL), tidak efisien (ia menggunakanStringBuffer
Builder dan melakukan beberapa hal lain yang lambat) Ini juga terlalu mudah untuk mengacaukannya.Sebaliknya saya akan menggunakan
URIBuilder
atau Spring'sorg.springframework.web.util.UriUtils.encodeQuery
atau Commons ApacheHttpClient
. Alasannya adalah Anda harus melarikan diri nama parameter kueri (yaitu jawaban BalusCq
) berbeda dari nilai parameter.Satu-satunya downside ke atas (yang saya temukan dengan menyakitkan) adalah URL bukan subset sebenarnya dari URI .
Kode sampel:
Karena saya hanya menautkan ke jawaban lain, saya menandai ini sebagai wiki komunitas. Jangan ragu untuk mengedit.
sumber
URLEncoder
adalah seperti kata javadoc yang bermaksud untuk menyandikan parameter string kueri sesuaiapplication/x-www-form-urlencoded
seperti yang dijelaskan dalam spesifikasi HTML: w3.org/TR/html4/interact/… . Beberapa pengguna memang bingung / menyalahgunakannya untuk menyandikan seluruh URI, seperti yang dilakukan penjawab saat ini.Anda harus terlebih dahulu membuat URI seperti:
Kemudian konversikan Uri ke string ASCII:
Sekarang string url Anda benar-benar dikodekan terlebih dahulu kami melakukan pengkodean url sederhana dan kemudian kami mengubahnya menjadi ASCII String untuk memastikan tidak ada karakter di luar US-ASCII yang tersisa dalam string. Inilah yang dilakukan browser.
sumber
URL.toURI()
tidak.+
penggantian spasi, tetapi menerima% 20 sehingga solusi ini bekerja lebih baik daripada BalusC, terima kasih!Guava 15 sekarang telah menambahkan satu set escapers URL langsung .
sumber
URLEncoder
.URLEncoder
tidak.Pustaka Komponen Apache Http menyediakan opsi yang rapi untuk membuat dan menyandikan param query -
Dengan penggunaan HttpComponents 4.x - URLEncodedUtils
Untuk penggunaan HttpClient 3.x - EncodingUtil
sumber
Berikut adalah metode yang dapat Anda gunakan dalam kode Anda untuk mengonversi string url dan memetakan parameter ke string url yang disandikan yang berisi parameter kueri.
sumber
Cetakan
Apa yang terjadi disini?
1. Pisahkan URL menjadi bagian-bagian struktural. Gunakan
java.net.URL
untuk itu.2. Encode setiap bagian struktural dengan benar!
3. Gunakan
IDN.toASCII(putDomainNameHere)
untuk Punycode menyandikan nama host!4. Gunakan
java.net.URI.toASCIIString()
untuk persen-encode, NFC dikodekan unicode - (lebih baik NFKC!). Untuk info lebih lanjut, lihat: Cara menyandikan URL ini dengan benarDalam beberapa kasus, disarankan untuk memeriksa apakah url sudah dikodekan . Juga ganti ruang yang disandikan '+' dengan ruang yang disandikan '% 20'.
Berikut adalah beberapa contoh yang juga akan berfungsi dengan baik
Solusi melewati sekitar 100 dari testcases yang disediakan oleh Web Plattform Tests .
sumber
Di android saya akan menggunakan kode ini:
Dimana
Uri
aandroid.net.Uri
sumber
Dalam kasus saya, saya hanya perlu melewatkan seluruh url dan mengkodekan hanya nilai dari setiap parameter. Saya tidak menemukan kode umum untuk melakukannya (!!) jadi saya membuat metode kecil ini untuk melakukan pekerjaan:
Ini menggunakan org.apache.commons.lang3.StringUtils
sumber
Anda dapat menggunakan kode follwing.
sumber
=
dan&
pemisah, yang tidak benar.