Apa perbedaan antara URI.escapedan CGI.escapedan mana yang harus saya gunakan?
Apa perbedaan antara URI.escapedan CGI.escapedan mana yang harus saya gunakan?
Jawaban:
Ada beberapa perbedaan kecil, tetapi poin pentingnya adalah yang URI.escapesudah usang di Ruby 1.9.2 ... jadi gunakan CGI::escapeatau ERB :: Util.url_encode .
Ada diskusi panjang tentang ruby-core untuk mereka yang tertarik yang juga menyebutkan WEBrick :: HTTPUtils.escape dan WEBrick :: HTTPUtils.escape_form .
ERB::Util.url_encodeyang benar digunakan %20 untuk ruang
Apa perbedaan antara kapak dan pedang dan yang mana yang harus saya gunakan? Yah itu tergantung pada apa yang perlu Anda lakukan.
URI.escapeseharusnya menyandikan string (URL) ke, yang disebut, " Persen-encoding ".
CGI::escapedatang dari spec CGI , yang menjelaskan bagaimana data harus dikodekan / decode antara server web dan aplikasi.
Sekarang, katakanlah Anda harus keluar dari URI di aplikasi Anda. Ini adalah kasus penggunaan yang lebih spesifik. Untuk itu, komunitas Ruby digunakan URI.escapeselama bertahun-tahun. Masalahnya URI.escapeadalah tidak bisa menangani spesifikasi RFC-3896.
URI.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at%23anchor&title=My%20Blog%20&%20Your%20Blog"
URI.escape ditandai sebagai usang:
Terlebih lagi URI.encode saat ini adalah gsub sederhana. Tetapi saya pikir itu harus membagi URI ke komponen, kemudian melarikan diri masing-masing komponen, dan akhirnya bergabung dengan mereka.
Jadi URI.encode saat ini dianggap berbahaya dan tidak digunakan lagi. Ini akan dihapus atau mengubah perilaku secara drastis.
Apa penggantinya saat ini?
Seperti yang saya katakan di atas, URI.encode saat ini salah pada tingkat spesifikasi. Jadi kami tidak akan memberikan penggantian yang tepat. Penggantian akan bervariasi sesuai dengan kasus penggunaannya.
Sayangnya tidak ada satu kata pun tentang hal itu di dokumen, satu-satunya cara untuk mengetahuinya adalah dengan memeriksa sumbernya, atau menjalankan skrip dengan peringatan di tingkat verbose ( -wW2) (atau menggunakan beberapa google-fu).
Beberapa mengusulkan untuk menggunakan CGI::Escapeparameter kueri, karena Anda tidak dapat menghindari seluruh URI:
CGI::escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http%3A%2F%2Fgoogle.com%2Ffoo%3Fbar%3Dat%23anchor%26title%3DMy+Blog+%26+Your+Blog"
CGI::escapeharus digunakan hanya untuk parameter kueri, tetapi hasilnya akan, sekali lagi, berlawanan dengan spesifikasi. Sebenarnya use-case yang paling umum adalah melarikan diri data formulir, seperti saat mengirim application/x-www-form-urlencodedpermintaan POST.
Disebutkan WEBrick::HTTPUtils.escapejuga tidak banyak perbaikan (sekali lagi itu hanya sederhana gsub, yaitu, IMO, bahkan pilihan yang lebih buruk daripada URI.escape):
WEBrick::HTTPUtils.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at%23anchor&title=My%20Blog%20&%20Your%20Blog"
Yang paling dekat dengan spec tampaknya adalah permata yang dapat dialamatkan :
require 'addressable/uri'
Addressable::URI.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at#anchor&title=My%20Blog%20&%20Your%20Blog"
Perhatikan, bahwa tidak seperti semua opsi sebelumnya, Addressable tidak luput #, dan ini adalah perilaku yang diharapkan. Anda ingin menyimpan #hash di jalur URI tetapi tidak di kueri URI.
Satu-satunya masalah yang tersisa adalah bahwa kami tidak lolos parameter kueri kami dengan benar, yang membawa kami pada kesimpulan: kita tidak boleh menggunakan metode tunggal untuk seluruh URI, karena tidak ada solusi yang sempurna (sejauh ini). Seperti yang Anda lihat &tidak luput dari "Blog Saya & Blog Anda". Kita perlu menggunakan bentuk pelolosan yang berbeda untuk permintaan, di mana pengguna dapat menempatkan karakter berbeda yang memiliki arti khusus dalam URL. Masukkan penyandian URL. Pengkodean URL harus digunakan untuk setiap nilai permintaan "mencurigakan", mirip dengan apa yang ERB::Util.url_encodedilakukan:
ERB::Util.url_encode "My Blod & Your Blog"
# => "My%20Blod%20%26%20Your%20Blog""
Ini keren tapi kami sudah meminta Addressable:
uri = Addressable::URI.parse("http://www.go.com/foo")
# => #<Addressable::URI:0x186feb0 URI:http://www.go.com/foo>
uri.query_values = {title: "My Blog & Your Blog"}
uri.normalize.to_s
# => "http://www.go.com/foo?title=My%20Blog%20%26%20Your%20Blog"
Kesimpulan:
URI.escapeatau serupaCGI::escapejika Anda hanya perlu pelarian bentukAddressablesalah satu permata Anda, Anda dapat mengurai URL terlebih dahulu, fi rubydoc.info/gems/addressable/Addressable/URI.heuristic_parse
Addressable:URL, Anda kemudian dapat memanggil semua metode instance di atasnya, mungkin salah satu dari mereka akan memberi Anda hasil yang diinginkan: rubydoc.info/gems/addressable/Addressable/URI
URI.escape mengambil parameter kedua yang memungkinkan Anda menandai apa yang tidak aman. Lihat APIDock:
CGI::escapebagus untuk keluar dari segmen teks sehingga mereka dapat digunakan dalam parameter kueri url (string setelah '?'). Misalnya jika Anda ingin memiliki parameter yang mengandung karakter slash di url, Anda CGI :: keluar dari string itu terlebih dahulu dan kemudian masukkan dalam url.
Namun di Rails Anda mungkin tidak akan menggunakannya secara langsung. Biasanya Anda gunakan hash.to_param, yang akan digunakan di CGI::escapebawah tenda.
URI::escapebagus untuk keluar dari url yang tidak lolos dengan benar. Misalnya beberapa situs web menampilkan url yang salah / tidak terhapus di tag jangkar mereka. Jika program Anda menggunakan url ini untuk mengambil lebih banyak sumber daya, OpenURI akan mengeluh bahwa url tidak valid. Anda perlu URI::escapeini untuk menjadikannya url yang valid. Jadi itu digunakan untuk melarikan diri dari seluruh string URI untuk membuatnya lebih baik Dalam kata-kata saya URI :: unescape membuat url dapat dibaca oleh manusia, dan URI :: escape membuatnya valid untuk browser.
Ini adalah istilah awam saya dan merasa bebas untuk memperbaikinya.
Perbedaannya adalah bahwa URI.escape tidak berfungsi ...
CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"
URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"
CGI.escape adalah untuk keluar dari nilai URL dalam string kueri. Semua karakter yang tidak termasuk dalam ALPHA, DIGIT, '_', '-', '.' dan '' rangkaian karakter diloloskan.
Tetapi itu akan membuat URL salah, karena url perlu memiliki '/', ':', '?', '[', '&', '=', Dan ';'. Mungkin lebih dari yang saya tidak bisa memikirkan bagian atas kepala saya.
URI.escape meninggalkan karakter URL itu sendiri, dan mencoba menemukan kunci dan nilai string kueri untuk melarikan diri. Namun ini benar-benar tidak dapat diandalkan karena nilai dapat memiliki semua jenis karakter yang mencegah pelarian yang mudah. Pada dasarnya, ini sudah terlambat. Tetapi jika URL dapat dijadikan sederhana (tidak ada '&' dan '=' dll dalam nilai-nilai), fungsi ini dapat digunakan untuk keluar dari karakter yang mungkin tidak terbaca atau ilegal.
Secara umum - selalu gunakan CGI.escape pada kunci dan nilai individual sebelum bergabung dengan '&' dan menambahkannya setelah '?'.
CGI.escape tidak berfungsi dengan OpenProject API. Itu mengkodekan [] ,: dan bukan +. Saya meretas ini bersama yang tampaknya bekerja sejauh ini untuk OpenProject's API. Tapi saya yakin itu kehilangan beberapa .gsub. Kemungkinannya hampir sama buruknya dengan URI.escape, tetapi itu tidak akan memberi Anda kesalahan yang usang.
class XXX
def self.encode(path)
path, query = path.split("?", 2)
return path if query.nil?
query = CGI.escape(query).gsub("%3A", ":").gsub("%3D","=").gsub("%5B","[").gsub("%5D","]").gsub("%2C",",").gsub("+","%20")
return [path,query].join("?")
end
end
XXX.encode("http://test.com/some/path?query=[box: \"cart\"]")
URI.encode("http://test.com/some/path?query=[box: \"cart\"]")
Kedua output:
=> " http://test.com/some/path?query=[box:%20%22cart%22] "
=> " http://test.com/some/path?query=[box:%20 % 22mulai% 22] "