如何在 Ruby 中对字符串进行 URL 编码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6714196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to URL encode a string in Ruby
提问by HRóDóLFR
How do I URI::encodea string like:
我如何URI::encode像这样的字符串:
\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a
to get it in a format like:
以如下格式获取它:
%124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A
as per RFC 1738?
根据 RFC 1738?
Here's what I tried:
这是我尝试过的:
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>'
Also:
还:
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>'
I looked all about the internet and haven't found a way to do this, although I am almost positive that the other day I did this without any trouble at all.
我查看了所有关于互联网的内容,但还没有找到一种方法来做到这一点,尽管我几乎可以肯定前几天我完全没有遇到任何麻烦。
回答by kain
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"
回答by Jenner La Fave
Nowadays, you should use ERB::Util.url_encodeor CGI.escape. The primary difference between them is their handling of spaces:
如今,您应该使用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.escapefollows the CGI/HTML forms specand gives you an application/x-www-form-urlencodedstring, which requires spaces be escaped to +, whereas ERB::Util.url_encodefollows RFC 3986, which requires them to be encoded as %20.
CGI.escape遵循CGI/HTML 表单规范并为您提供一个application/x-www-form-urlencoded字符串,该字符串要求将空格转义为+,而ERB::Util.url_encode遵循RFC 3986要求将它们编码为%20.
See "What's the difference between URI.escape and CGI.escape?" for more discussion.
有关更多讨论,请参阅“ URI.escape 和 CGI.escape 之间的区别是什么?”。
回答by Jared Beck
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"
Taken from @J-Rou's comment
摘自@J-Rou 的评论
回答by Alexey Shein
You can use Addressable::URIgem for that:
您可以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"
It uses more modern format, than CGI.escape, for example, it properly encodes space as %20and not as +sign, you can read more in "The application/x-www-form-urlencoded type" on Wikipedia.
它使用更现代的格式,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"
回答by foomip
I created a gem to make URI encoding stuff cleaner to use in your code. It takes care of binary encoding for you.
我创建了一个 gem 来使 URI 编码内容更清晰,以便在您的代码中使用。它会为您处理二进制编码。
Run gem install uri-handler, then use:
运行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"
It adds the URI conversion functionality into the String class. You can also pass it an argument with the optional encoding string you would like to use. By default it sets to encoding 'binary' if the straight UTF-8 encoding fails.
它将 URI 转换功能添加到 String 类中。您还可以向它传递一个带有您要使用的可选编码字符串的参数。默认情况下,如果直接 UTF-8 编码失败,它会设置为编码“二进制”。
回答by kangkyu
I was originally trying to escape special characters in a file name only, not on the path, from a full URL string.
我最初只是试图从完整的 URL 字符串中转义文件名中的特殊字符,而不是路径中的特殊字符。
ERB::Util.url_encodedidn't work for my use:
ERB::Util.url_encode不适用于我的用途:
helper.send(:url_encode, "http://example.com/?a=")
# => "http%3A%2F%2Fexample.com%2F%3Fa%3D%09%0D"
Based on two answers in "Why is URI.escape() marked as obsolete and where is this REGEXP::UNSAFE constant?", it looks like URI::RFC2396_Parser#escapeis better than using URI::Escape#escape. However, they both are behaving the same to me:
基于“为什么 URI.escape() 被标记为过时以及这个 REGEXP::UNSAFE 常量在哪里?”中的两个答案,它看起来URI::RFC2396_Parser#escape比使用URI::Escape#escape. 但是,他们对我的行为都一样:
URI.escape("http://example.com/?a=")
# => "http://example.com/?a=%09%0D"
URI::Parser.new.escape("http://example.com/?a=")
# => "http://example.com/?a=%09%0D"
回答by Glenn 'devalias'
If you want to "encode" a full URL without having to think about manually splitting it into its different parts, I found the following worked in the same way that I used to use URI.encode:
如果您想“编码”一个完整的 URL 而不必考虑手动将其拆分为不同的部分,我发现以下工作方式与我以前使用的方式相同URI.encode:
URI.parse(my_url).to_s
回答by Thiago Falcao
Code:
代码:
str = "http://localhost/with spaces and spaces"
encoded = URI::encode(str)
puts encoded
Result:
结果:
http://localhost/with%20spaces%20and%20spaces

