URI.escape和CGI.escape有什么区别?
有一些小的差异,但重要的一点是,URI.escape
一直在红宝石1.9.2 deprecated ...所以使用CGI::escape
或ERB::Util.url_encode。
有一个长期的讨论on ruby-core有兴趣的人还提到WEBrick::HTTPUtils.escape和WEBrick::HTTPUtils.escape_form。
URI.escape采用第二个参数,可以让您标记什么是不安全的。见APIDock:
大答案@Robert斯派克。 – lightyrs 2013-03-30 08:03:19
CGI::escape
适用于转义文本段,以便它们可以用于url查询参数('?'之后的字符串)。例如,如果你想在url中包含斜线字符参数,你首先将CGI :: escape字符串转义出来,然后将其插入到url中。
但是在Rails中你可能不会直接使用它。通常你使用hash.to_param
,这将使用CGI::escape
。
URI::escape
有利于逃避这是不正确转义的URL。例如,一些网站在其标记标签中输出错误/未转义的网址。如果您的程序使用这些网址获取更多资源,OpenURI会抱怨这些网址无效。您需要URI::escape
这些才能使其成为有效的网址。所以它被用来转义整个URI字符串以使其正确。用我的话来说,URI :: unescape使人类可读的URL,URI :: escape使它对浏览器有效。
这些是我的外行人的任期,并随时纠正这些问题。
斧头和剑之间有什么区别,我应该使用哪一个?那么它取决于你需要做什么。
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。编码被认为是有害的并被弃用。这会使 被删除或急剧改变行为。
什么是更换在这个时候?
正如我上面所说的,当前的URI.encode在规范级别是错误的。所以我们 将不会提供确切的替换。更换将根据其 用例而有所不同。
不幸的是,没有一个关于它的单个字的文档,了解它是检查源,或运行在详细级别(-wW2
)警告脚本的唯一途径(或使用一些谷歌福)。
一些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
,这是,海事组织,甚至比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"
注意,不像以前所有的选项,可寻址没有逃脱#
,这是预期的行为。要保持#
散列URI路径,但不是在URI查询。
唯一剩下的问题是,我们没有正确地逃过我们的查询参数,这使我们得出结论:我们不应该对整个URI一个方法,因为没有完美的解决方案(到目前为止)。 正如你看到的&
不是从“我的博客&你的Blog”逃过一劫。我们需要为查询参数使用不同形式的转义,用户可以在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
如果你只需要形式逃逸 - 如果需要使用URI来工作,使用可寻址,它提供了URL编码,编码形式和规范化的URL。
- 如果它是一个Rails项目,退房 “How do I URL-escape a string in Rails?”
非常感谢您的信息。它确实摆脱了一些锄头测试警告。下面有一把耙子和一把锄头。 – 2014-09-24 07:18:20
很好的解释@Ernest,但问题在于它不适用于我不想创建(并且无法控制)的外部URL。例如抓取工具从网页中读取URL,然后尝试访问这些URL(在访问之前需要对其进行编码)。 – 2014-11-09 23:23:40
@amit_saxena如果你能提供具有'Addressable'为你的宝石之一,你可以先解析URL,f.i. http://www.rubydoc.info/gems/addressable/Addressable/URI.heuristic_parse – Ernest 2014-11-10 15:50:58
不同的是,URI.escape是不工作...
CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"
URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"
只是为了增加迷惑 - 我只是看到了http://stackoverflow.com/questions/4967608/in-ruby-rails-how-can-i-encode-escape-special-characters-in-urls 哪里评论有人提到,CGI逃生使用“+”,而不是20%的空间,而这违反了“规范” ... – 2012-07-19 11:24:25
另一种方法是使用'ERB :: Util.url_encode',妥善使用'%20'的空间 – riffraff 2012-10-16 08:40:39
AFAIK,URI.escape在1.9.2和1.9.3中不推荐使用。我错过了什么? – Ernest 2012-10-23 16:56:18