webentwicklung-frage-antwort-db.com.de

Ruby URL-Codierungszeichenfolge

Wie kann ich URI :: einen String wie folgt kodieren:

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

So erhalten Sie es in einem Format wie:

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

(gemäß RFC 1738)

Folgendes habe ich versucht:

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>'

Ebenfalls,

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>'

Ich habe mich im Internet umgesehen und keinen Weg gefunden (oder wahrscheinlich verpasst), dies zu tun, obwohl ich beinahe sicher bin, dass ich dies neulich überhaupt ohne Probleme getan habe.

Vielen Dank!

126
HRÓÐÓLFR
require 'uri'
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 URI::encode(str)

UPDATE: siehe Kommentar unten Ruby-URL-Codierungszeichenfolge

167
kain
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"

Entnommen dem Kommentar von @ J-Rou

70
Jared Beck

Heutzutage sollten Sie ERB::Util.url_encode Oder CGI.escape Verwenden. Der Hauptunterschied zwischen ihnen ist der Umgang mit Leerzeichen:

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

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

CGI.escape Folgt der CGI/HTML-Formularspezifikation und gibt Ihnen einen application/x-www-form-urlencoded - String, bei dem Leerzeichen in + Maskiert werden müssen, wohingegen ERB::Util.url_encode folgt RFC 3986 , was erfordert, dass sie als %20 codiert werden.

Siehe diese Antwort für mehr Diskussion.

68
Jenner La Fave

Sie können Addressable::URI Juwel dafür:

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" 

Es verwendet ein moderneres Format als CGI.escape, zum Beispiel kodiert es den Raum korrekt als %20 und nicht als +, lesen Sie mehr in Wikipedia-Artikel

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" 
8
Alexey Shein

Ich habe einen Edelstein geschaffen, um Uri-Codierungs-Inhalte sauberer zu machen, damit sie in Ihrem Code verwendet werden können. Es kümmert sich für Sie um die Binärkodierung (einige Beispiele wurden im obigen Code hinzugefügt).

Lauf 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"

Es fügt der String-Klasse die URI-Konvertierungsfunktionalität hinzu. Sie können ihm auch ein Argument mit der optionalen Codierungszeichenfolge übergeben, die Sie verwenden möchten (standardmäßig wird die Codierung auf "Binär" festgelegt, wenn die direkte UTF-8-Codierung fehlschlägt).

5
foomip

Ich habe ursprünglich versucht, Sonderzeichen nur für den Dateinamen (nicht für den Pfad) aus der vollständigen URL-Zeichenfolge zu entfernen. ERB::Util.url_encode hat für mich nicht funktioniert.

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

Basierend auf 2 Antworten von verschiedenen SO Frage , sieht es aus wie URI::RFC2396_Parser#escape ist besser als URI::Escape#escape. Beide verhalten sich mir gegenüber jedoch gleich.

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
kangkyu

Code:

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

Ergebnis:

http://localhost/with%20spaces%20and%20spaces
0
Thiago Falcao

Wenn Sie eine vollständige URL 'codieren' möchten, ohne sie manuell in verschiedene Teile aufteilen zu müssen, haben die folgenden Schritte auf die gleiche Weise funktioniert wie bei der Verwendung von URI.encode:

URI.parse(my_url).to_s
0