URI.escape
和CGI.escape
之间有什么区别?我应该使用哪一个?
答案 0 :(得分:205)
斧头和剑之间有什么区别我应该使用哪一个?那么它取决于你需要做什么。
URI.escape
应该将字符串(URL)编码为所谓的“Percent-encoding”。
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
)运行脚本(或使用一些谷歌) -fu)。
有些proposed要使用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"
最接近规范似乎是Addressable宝石:
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编码。 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
答案 1 :(得分:115)
存在一些小的差异,但重要的是,{1.9}中的URI.escape
已deprecated ...所以请使用CGI::escape
或ERB::Util.url_encode。< / p>
对于那些感兴趣的人,on ruby-core和WEBrick::HTTPUtils.escape进行了长时间的讨论WEBrick::HTTPUtils.escape_form。
答案 2 :(得分:9)
URI.escape采用第二个参数,可以标记出什么是不安全的。见APIDock:
答案 3 :(得分:6)
CGI::escape
适用于转义文本段,因此可以在url查询参数('?'后面的字符串)中使用它们。例如,如果您希望在url中包含包含斜杠字符的参数,则CGI ::首先转义该字符串,然后将其插入url中。
但是在Rails中你可能不会直接使用它。通常您使用hash.to_param
,它将使用CGI::escape
。
URI::escape
适用于转义未正确转义的网址。例如,某些网站在其锚标记中输出错误/未转义的网址。如果您的程序使用这些网址获取更多资源,OpenURI会抱怨网址无效。您需要URI::escape
这些才能使其成为有效的网址。因此它用于转义整个URI字符串以使其正确。在我的单词URI :: unescape中,人类可以读取url,而URI :: escape使它对浏览器有效。
这些是我的外行任期,随时可以纠正这些。
答案 4 :(得分:2)
区别在于URI.escape不起作用......
CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"
URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"
答案 5 :(得分:0)
CGI.escape用于转义查询字符串中的URL值。不属于ALPHA,DIGIT,'_','-','。'的所有字符和''字符集被转义。
但这将使URL不正确,因为url需要具有'/',':','?','[','&','='和';'。也许我想不到的更多。
URI.escape仅保留这些URL字符,然后尝试查找要转义的查询字符串键和值。但是,实际上不能依赖于此,因为值可以包含各种字符,从而容易逃脱。基本上,为时已晚。但是,如果可以将URL简化为简单的值(值中没有'&'和'='等),则可以使用此函数来转义可能不可读或非法的字符。
通常-在将各个键和值与'&'联接并在'?'之后添加它们之前,请始终对各个键和值使用CGI.escape。
答案 6 :(得分:0)
CGI.escape不适用于OpenProject API。它对[] ,:而不是+进行编码。我一起破解了这一点,到目前为止看来,它对于OpenProject的API仍然有效。但我确定它缺少一些.gsub。它可能几乎与URI.escape一样糟糕,但不会给您带来过时的错误。
<list>
<message ref="00001">
<entry>
<orderid>P001</orderid>
<timestamp>20200109085816092</timestamp>
</entry>
</message>
<message ref="00002">
<entry>
<orderid>P002</orderid>
<timestamp>20200109085813556</timestamp>
</entry>
</message>
<message ref="00003">
<entry>
<orderid>P003</orderid>
<timestamp>20200109085814612</timestamp>
</entry>
</message>
<message ref="00004"/>
<message ref="00005"/>
<message ref="00006"/>
两个输出:
=>“ http://test.com/some/path?query=[box:%20%22cart%22]”
=>“ http://test.com/some/path?query=[box:%20%22cart%22]”