如何在Ruby中对字符串进行URL编码

t1rydlwq  于 12个月前  发布在  Ruby
关注(0)|答案(8)|浏览(176)

如何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


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


我看了所有关于互联网和还没有找到一种方法来做到这一点,虽然我几乎肯定,有一天我这样做,没有任何麻烦。

fhg3lkii

fhg3lkii1#

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"

字符串

qlvxas9a

qlvxas9a2#

现在,你应该使用ERB::Util.url_encodeCGI.escape。它们之间的主要区别是它们对空格的处理:

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

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

字符串
CGI.escape遵循CGI/HTML表单规范,并提供一个application/x-www-form-urlencoded字符串,这需要将空格转义为+,而ERB::Util.url_encode遵循RFC 3986,这需要将它们编码为%20
请参阅“URI.escape和CGI.escape之间有什么区别?”了解更多讨论。

8zzbczxx

8zzbczxx3#

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的评论

qlzsbp2j

qlzsbp2j4#

我最初试图从完整的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"

字符串
基于“https://stackoverflow.com/questions/34274838/why-is-uri-escape-marked-as-obsolete-and-where-is-this-regexpunsafe-constant“中的两个答案,看起来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"


更新:我想它是从Ruby 3.0开始的,URI.escape不再工作了。除了URI::Parser.new.escape,我还没有找到替代品。

kr98yfug

kr98yfug5#

你可以使用Addressable::URI gem来实现:

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"

kx7yvsdv

kx7yvsdv6#

代码:

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

字符串
测试结果:

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

t2a7ltrp

t2a7ltrp7#

我创建了一个gem来使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转换功能添加到String类中。您也可以向它传递一个参数,其中包含您想要使用的可选编码字符串。默认情况下,如果直接UTF-8编码失败,它将设置为编码'binary'。

ioekq8ef

ioekq8ef8#

如果你想“编码”一个完整的URL,而不必考虑手动将其拆分为不同的部分,我发现下面的工作方式与我使用URI.encode的方式相同:

URI.parse(my_url).to_s

字符串

相关问题