URI.escape和CGI.escape有什么区别?
URI.escape
和CGI.escape
什么区别,我应该使用哪一个?
有一些小的差异,但重要的一点是URI.escape
在Ruby 1.9.2中已被弃用 …所以使用CGI::escape
或ERB :: Util.url_encode 。
对于那些感兴趣的人来说, ruby-core还有很长时间的讨论,其中还提到了WEBrick :: HTTPUtils.escape和WEBrick :: HTTPUtils.escape_form 。
斧头和剑之间有什么区别,我应该使用哪一个? 那么这取决于你需要做什么。
URI.escape
应该将string(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分解成组件,然后转义每个组件,最后join它们。
所以当前的URI.encode被认为是有害的,并被弃用。 这将被删除或改变行为急剧。
什么是在这个时候更换?
正如我上面所说,目前的URI.encode在规范级别是错误的。 所以我们不会提供确切的replace。 replace将根据其使用情况而有所不同。
不幸的是,在文档中没有关于它的一个单词,要知道它的唯一方法是检查源代码,或在详细级别( -wW2
)(或使用一些谷歌福)运行脚本与警告。
一些人build议使用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"
最接近规范似乎是可寻址的gem:
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不会逃避#
,这是预期的行为。 您希望将#hash保留在URIpath中,而不是在URI查询中。
剩下的唯一问题是我们没有正确地转义我们的查询参数,这使我们得出结论:对于整个URI,我们不应该使用单一的方法,因为目前还没有完美的解决scheme。 正如你所见&
并没有从“我的博客和你的博客”逃脱。 我们需要对查询参数使用不同的转义forms,用户可以在URL中放置不同的特殊字符。 inputurl编码。 每个“可疑”查询值都应该使用URL编码,类似于ERB::Util.url_encode
所做的:
ERB::Util.url_encode "My Blod & Your Blog" # => "My%20Blod%20%26%20Your%20Blog""
这很酷,但我们已经要求可寻址:
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
escape - 如果您需要使用URI,请使用Addressable,它提供URL编码,表单编码和URL规范化。
- 如果是Rails项目,请查看“ 如何在URL中转义string? ”
URI.escape带有第二个参数,可以让你标记什么是不安全的。 见APIDock:
CGI::escape
对于转义文本段是很好的,所以它们可以用在url查询参数('?'之后的string)中。 例如,如果你想要在url中包含斜线字符的参数,你可以先将CGI :: escapestring转义出来,然后将其插入到url中。
但是在Rails中你可能不会直接使用它。 通常你使用hash.to_param
,它将在hash.to_param
使用CGI::escape
。
URI::escape
是很好的转义不正确转义的url。 例如,一些网站在他们的锚标签中输出错误/非转义的url。 如果你的程序使用这些URL来获取更多的资源,OpenURI会抱怨这些URL是无效的。 你需要URI::escape
这些使其成为一个有效的url。 所以它被用来转义整个URIstring以使其正确。 用我的话来说,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"