URI.escape和CGI.escape有什么区别?

Tom*_*man 137 ruby

什么之间的区别URI.escape,并CGI.escape和我应该使用哪一个?

Ern*_*est 215

斧头和剑之间有什么区别我应该使用哪一个?那取决于你需要做什么.

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"
Run Code Online (Sandbox Code Playgroud)

URI.escape 被标记为过时:

此外,当前的URI.encode是简单的gsub.但我认为它应该将URI拆分为组件,然后转义每个组件,最后加入它们.

因此,当前的URI.encode被认为是有害的并且已被弃用.这将被删除或彻底改变行为.

目前有什么替代品?

如上所述,当前URI.encode在规范级别上是错误的.所以我们不会提供确切的替代品.替换因用例而异.

https://bugs.ruby-lang.org/issues/4167

不幸的是,在文档中没有关于它的单词,了解它的唯一方法是检查源,或者在详细级别(-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"
Run Code Online (Sandbox Code Playgroud)

CGI::escape应仅用于查询参数,但结果将再次针对规范.实际上,最常见的用例是转发表单数据,例如发送application/x-www-form-urlencodedPOST请求时.

还提到了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" 
Run Code Online (Sandbox Code Playgroud)

最接近规范似乎是可寻址的宝石:

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"
Run Code Online (Sandbox Code Playgroud)

请注意,与以前的所有选项不同,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""
Run Code Online (Sandbox Code Playgroud)

这很酷但我们已经要求可寻址:

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"
Run Code Online (Sandbox Code Playgroud)

结论:

  • 不要使用URI.escape或类似
  • 使用CGI::escape,如果你只需要形式逃生
  • 如果您需要使用URI,请使用Addressable,它提供URL编码,表单编码和规范化URL.
  • 如果它是一个Rails项目,请查看" 如何URL转义Rails中的字符串? "


Mar*_*une 119

有一些小的差异,但重要的是在Ruby 1.9.2中URI.escape已经弃用了...所以使用CGI::escapeERB :: Util.url_encode.

对于那些感兴趣的人,有一个关于ruby-core的长期讨论,其中也提到了WEBrick :: HTTPUtils.escapeWEBrick :: HTTPUtils.escape_form.

  • 另一种方法是使用`ERB :: Util.url_encode`来正确使用'%20`作为空格 (14认同)
  • 只是为了增加混乱 - 我刚看到http://stackoverflow.com/questions/4967608/in-ruby-rails-how-can-i-encode-escape-special-characters-in-urls上有人提到的评论cgi转义使用'+'而不是%20作为空格,并且它与'spec'相对... (11认同)
  • http://www.ruby-doc.org/stdlib-2.0.0/libdoc/uri/rdoc/URI/Escape.html.ruby 2.0.0中有URI.escape模块.为什么要弃用? (4认同)

Rob*_*her 9

URI.escape采用第二个参数,可以标记出什么是不安全的.见APIDock:

http://apidock.com/ruby/CGI/escape/class

http://apidock.com/ruby/URI/Escape/escape


lul*_*ala 6

CGI::escape有利于转义文本段,因此可以在url查询参数('?'之后的字符串)中使用它们.例如,如果您希望在url中包含包含斜杠字符的参数,则CGI ::首先转义该字符串,然后将其插入url中.

但是在Rails中你可能不会直接使用它.通常你使用hash.to_param,将CGI::escape在引擎盖下使用.


URI::escape有利于逃避未正确逃脱的网址.例如,某些网站在其锚标记中输出错误/未转义的网址.如果您的程序使用这些网址获取更多资源,OpenURI会抱怨网址无效.你需要URI::escape这些使它成为一个有效的网址.因此它用于转义整个URI字符串以使其正确.在我的单词URI :: unescape中,人类可以读取url,而URI :: escape使它对浏览器有效.

这些是我的外行任期,随时可以纠正这些.