URL रूबी में स्ट्रिंग को कैसे एनकोड करता है


135

मैं कैसे URI::encodeएक स्ट्रिंग की तरह:

\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a

इसे एक प्रारूप में प्राप्त करने के लिए जैसे:

%124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A

आरएफसी 1738 के अनुसार?

यहाँ मैंने क्या कोशिश की है:

irb(main):123:0> URI::encode "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a"
ArgumentError: invalid byte sequence in UTF-8
    from /usr/local/lib/ruby/1.9.1/uri/common.rb:219:in `gsub'
    from /usr/local/lib/ruby/1.9.1/uri/common.rb:219:in `escape'
    from /usr/local/lib/ruby/1.9.1/uri/common.rb:505:in `escape'
    from (irb):123
    from /usr/local/bin/irb:12:in `<main>'

इसके अलावा:

irb(main):126:0> CGI::escape "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a"
ArgumentError: invalid byte sequence in UTF-8
    from /usr/local/lib/ruby/1.9.1/cgi/util.rb:7:in `gsub'
    from /usr/local/lib/ruby/1.9.1/cgi/util.rb:7:in `escape'
    from (irb):126
    from /usr/local/bin/irb:12:in `<main>'

मैंने इंटरनेट के बारे में सब देखा और ऐसा करने का कोई तरीका नहीं पाया, हालाँकि मैं लगभग सकारात्मक हूँ कि दूसरे दिन मैंने बिना किसी परेशानी के ऐसा किया।


1
रूबी 1.9 का उपयोग करने पर शायद उपयोगी हो: yehudakatz.com/2010/05/05/…
Apneadiving

जवाबों:


179
str = "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a".force_encoding('ASCII-8BIT')
puts CGI.escape str


=> "%124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A"

2
force_encoding('binary')एक अधिक स्व-दस्तावेजीकरण विकल्प हो सकता है।
म्यू

63
उन्होंने उस विधि को हटा दिया, CGI.escapeइसके बजाय * * का उपयोग करें। -> http://www.ruby-forum.com/topic/207489#903709 । आपको URI.www_form_encode* URI.www_form_encode_component* का उपयोग करने में भी सक्षम होना चाहिए , लेकिन मैंने कभी भी उन का उपयोग नहीं किया है
J-Rou

2
यहां कोई जरूरत नहीं require 'open-uri'है। क्या आपका मतलब था require 'uri'?
पीजे

1
@ J-Rou, CGI.escape पूरे URL से बच सकता है, यह चुनिंदा रूप से क्वेरी पैरामीटर से बचता नहीं है, उदाहरण के लिए, यदि आप 'a=&!@&b=&$^'CGI.escape से गुजरते हैं, तो यह क्वेरी सेपरेटर के साथ पूरी चीज़ से बच जाएगा, &इसलिए इसे केवल क्वेरी मान के लिए उपयोग किया जा सकता है। मैं addressableमणि का उपयोग करने का सुझाव देता हूं , यह उरोजों के साथ काम करने में अधिक बौद्धिक है।
अलेक्जेंडर.लज्जुस्किन

मुझे दूरस्थ सर्वर पर फ़ाइलों तक पहुंचने की आवश्यकता थी। CGI के साथ एन्कोडिंग ने काम नहीं किया, लेकिन URI.encode ने ठीक काम किया।
1934

82

आजकल, आप का उपयोग करना चाहिए ERB::Util.url_encodeया CGI.escape। उनके बीच प्राथमिक अंतर उनके रिक्त स्थान की हैंडलिंग है:

>> ERB::Util.url_encode("foo/bar? baz&")
=> "foo%2Fbar%3F%20baz%26"

>> CGI.escape("foo/bar? baz&")
=> "foo%2Fbar%3F+baz%26"

CGI.escapeCGI / HTML फॉर्मूले का अनुसरण करता है और आपको एक application/x-www-form-urlencodedस्ट्रिंग देता है , जिसके लिए रिक्त स्थान से बचने की आवश्यकता होती है +, जबकि RFC 3986 काERB::Util.url_encode अनुसरण करता है , जिसके लिए उन्हें एन्कोडेड होना चाहिए ।%20

देखें " क्या URI.escape और CGI.escape? बीच क्या अंतर है और अधिक चर्चा के लिए"।


70
str = "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a"
require 'cgi'
CGI.escape(str)
# => "%124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A"

@ J-Rou की टिप्पणी से लिया गया


11

आप उसके लिए Addressable::URIमणि का उपयोग कर सकते हैं :

require 'addressable/uri'   
string = '\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a'
Addressable::URI.encode_component(string, Addressable::URI::CharacterClasses::QUERY)
# "%5Cx12%5Cx34%5Cx56%5Cx78%5Cx9a%5Cxbc%5Cxde%5Cxf1%5Cx23%5Cx45%5Cx67%5Cx89%5Cxab%5Cxcd%5Cxef%5Cx12%5Cx34%5Cx56%5Cx78%5Cx9a" 

CGI.escapeउदाहरण के लिए, यह तुलना में अधिक आधुनिक प्रारूप का उपयोग करता है , यह ठीक से अंतरिक्ष को सांकेतिक शब्दों में बदलना है , %20न कि +संकेत के रूप में , आप विकिपीडिया पर " एप्लीकेशन / x-www-form-urlencoded प्रकार " में अधिक पढ़ सकते हैं ।

2.1.2 :008 > CGI.escape('Hello, this is me')
 => "Hello%2C+this+is+me" 
2.1.2 :009 > Addressable::URI.encode_component('Hello, this is me', Addressable::URI::CharacterClasses::QUERY)
 => "Hello,%20this%20is%20me" 

इसके अलावा इस तरह कर सकते हैं: CGI.escape('Hello, this is me').gsub("+", "%20") => Hello%2C%20this%20is%20me"यदि कोई जवाहरात का उपयोग नहीं करना चाहते हैं
Raccoon

5

मैंने आपके कोड में उपयोग करने के लिए URI एन्कोडिंग स्टफ क्लीनर बनाने के लिए एक रत्न बनाया। यह आपके लिए बाइनरी एन्कोडिंग का ख्याल रखता है।

चलाएं gem install uri-handler, फिर उपयोग करें:

require 'uri-handler'

str = "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a".to_uri
# => "%124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A"

यह स्ट्रिंग वर्ग में URI रूपांतरण कार्यक्षमता जोड़ता है। आप इसे वैकल्पिक एन्कोडिंग स्ट्रिंग के साथ एक तर्क भी दे सकते हैं जिसका आप उपयोग करना चाहते हैं। यदि सीधे UTF-8 एन्कोडिंग विफल हो जाता है तो डिफ़ॉल्ट रूप से यह 'बाइनरी' को एन्कोडिंग पर सेट करता है।


2

कोड:

str = "http://localhost/with spaces and spaces"
encoded = URI::encode(str)
puts encoded

परिणाम:

http://localhost/with%20spaces%20and%20spaces

यदि प्राप्त करने वाला सर्वर पुराना है, तो वह CGI.escape के लिए अच्छी प्रतिक्रिया नहीं दे सकता है। यह अभी भी एक वैध विकल्प है।
cesartalves

2

मैं मूल रूप से एक फ़ाइल नाम में विशेष वर्णों से बचने की कोशिश कर रहा था, पथ पर नहीं, एक पूर्ण URL स्ट्रिंग से।

ERB::Util.url_encode मेरे उपयोग के लिए काम नहीं किया:

helper.send(:url_encode, "http://example.com/?a=\11\15")
# => "http%3A%2F%2Fexample.com%2F%3Fa%3D%09%0D"

" क्यों URI.escape () को अप्रचलित के रूप में चिह्नित किया गया है और यह REGEXP :: UNSAFE स्थिर है? " में दो उत्तरों के आधार पर , ऐसा लगता है कि यह URI::RFC2396_Parser#escapeउपयोग करने से बेहतर है URI::Escape#escape। हालाँकि, वे दोनों मेरे साथ समान व्यवहार कर रहे हैं:

URI.escape("http://example.com/?a=\11\15")
# => "http://example.com/?a=%09%0D"
URI::Parser.new.escape("http://example.com/?a=\11\15")
# => "http://example.com/?a=%09%0D"

2

यदि आप एक पूर्ण URL को "एनकोड" करना चाहते हैं, तो बिना उसके अलग-अलग हिस्सों में मैन्युअल रूप से विभाजित करने के बारे में सोचने के लिए, मैंने पाया कि निम्नलिखित उसी तरह से काम करता है जिस तरह से मैं उपयोग करता था URI.encode:

URI.parse(my_url).to_s
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.