Answers:
两者之间有一些细微的差别,但重要的一点是Ruby 1.9.2中URI.escape
已弃用 ...,因此请使用CGI::escape
或ERB :: Util.url_encode。
在ruby-core上有很多有兴趣的人进行长期讨论,其中还提到了WEBrick :: HTTPUtils.escape和WEBrick :: HTTPUtils.escape_form。
ERB::Util.url_encode
正确使用%20
空间
斧头和剑有什么区别,我应该使用哪把?好吧,这取决于您需要做什么。
URI.escape
应该将字符串(URL)编码为所谓的“ 百分比编码 ”。
CGI::escape
来自CGI规范,该规范描述了如何在Web服务器和应用程序之间对数据进行编码/解码。
现在,假设您需要在应用程序中转义URI。这是一个更具体的用例。为此,Ruby社区使用URI.escape
了多年。问题URI.escape
在于它无法处理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
被标记为过时的:
此外,当前的URI.encode是简单的gsub。但是我认为它应该将URI拆分为组件,然后转义每个组件,最后加入它们。
因此,当前的URI.encode被视为有害和不推荐使用。这将被删除或彻底改变行为。
这时的替代品是什么?
正如我上面所说,当前的URI.encode在规范级别上是错误的。因此,我们将不提供确切的替代品。替换将因其用例而异。
不幸的是,文档中对此一言不发,唯一了解它的方法是检查源代码,或在详细级别(-wW2
)中运行带有警告的脚本(或使用一些google-fu)。
有人建议将其CGI::Escape
用于查询参数,因为您无法转义整个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::escape
应该仅用于查询参数,但结果将再次违反规范。实际上,最常见的用例是转义表单数据,例如在发送application/x-www-form-urlencoded
POST请求时。
还提到了WEBrick::HTTPUtils.escape
很多改进(同样,这只是一个简单的gsub
,即IMO,甚至比糟糕的选择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"
与规格最接近的似乎是可寻址宝石:
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"
注意,与以前的所有选项不同,Addressable不会转义#
,这是预期的行为。您想将#
散列保留在URI路径中,而不要保留在URI查询中。
剩下的唯一问题是我们没有适当地转义查询参数,这使我们得出结论:我们不应该对整个URI使用单个方法,因为到目前为止还没有完美的解决方案。如您所见&
,“我的博客和您的博客”并未逃脱。我们需要对查询参数使用不同的转义形式,用户可以在URL中放置具有特殊含义的不同字符。输入网址编码。URL编码应用于每个“可疑”查询值,类似于ERB::Util.url_encode
:
ERB::Util.url_encode "My Blod & Your Blog"
# => "My%20Blod%20%26%20Your%20Blog""
很酷,但是我们已经需要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"
结论:
URI.escape
或类似CGI::escape
,如果你只需要形成逃生Addressable
作为自己的宝石之一,则可以先解析URL,网址为rubydoc.info/gems/addressable/Addressable/URI.heuristic_parse
Addressable:URL
,然后可以在其上调用所有实例方法,也许其中之一将为您带来所需的结果:rubydoc.info/gems/addressable/Addressable/URI
URI.escape使用第二个参数,该参数可让您标记不安全的内容。请参阅APIDock:
CGI::escape
是用于转义文本段的好方法,因此可以在url查询参数(“?”之后的字符串)中使用它们。例如,如果要在URL中包含包含斜杠字符的参数,则应先CGI :: escape该字符串,然后将其插入URL。
但是在Rails中,您可能不会直接使用它。通常您使用hash.to_param
,它将CGI::escape
在引擎盖下使用。
URI::escape
有助于转义未正确转义的网址。例如,某些网站在其锚标记中输出错误/未转义的网址。如果您的程序使用这些URL来获取更多资源,则OpenURI将抱怨这些URL无效。您需要URI::escape
这些使其成为有效的URL。因此,它用于转义整个URI字符串以使其正确。用我的话说,URI :: unescape使URL可以被人类读取,而URI :: escape使它对浏览器有效。
这些是我的外行术语,可以随时更正。
区别在于URI.escape无法正常工作...
CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"
URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"
CGI.escape用于转义查询字符串中的URL值。所有不属于ALPHA,DIGIT,'_','-','。'的字符 和''字符集被转义。
但这会使URL不正确,因为URL需要具有'/','::,'?','[','&','='和';'。也许还有更多我想不到的东西。
URI.escape仅保留这些URL字符,然后尝试查找要转义的查询字符串键和值。但是,实际上不能依赖于此,因为值可以具有各种字符,从而容易逃脱。基本上,为时已晚。但是,如果可以将URL简化为简单的值(值中没有'&'和'='等),则可以使用此函数来转义可能不可读或非法的字符。
通常,在将各个键和值与'&'联接并在'?'之后添加它们之前,请始终对各个键和值使用CGI.escape。
CGI.escape不适用于OpenProject API。它对[] ,:而不是+进行编码。我一起破解了这一点,到目前为止看来,它对于OpenProject的API仍然有效。但我确定它缺少一些.gsub。它可能几乎与URI.escape一样糟糕,但不会给您过时的错误。
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\"]")
两种输出:
=>“ http://test.com/some/path?query= [框:%20%22cart%22] ”
=>“ http://test.com/some/path?query= [框:%20 %22cart%22] “