14

因此,我尝试使用 Rails URL 助手 ( page_url) 创建包含特殊字符的 URL,包括与号。大多数情况都像您期望的那样工作:

(rdb:1) page_url('foo', :host => 'host')
"http://host/pages/foo"
(rdb:1) page_url('foo_%_bar', :host => 'host')
"http://host/pages/foo_%25_bar"

但由于某些奇怪的原因,与号没有被转义:

(rdb:1) page_url('foo_&_bar', :host => 'host')
"http://host/pages/foo_&_bar"

如果我预先逃脱它们,它们就会被破坏:

(rdb:1) page_url('foo_%26_bar', :host => 'host')
"http://host/pages/foo_%2526_bar"

CGI::escape,另一方面,可以很好地逃脱它们:

(rdb:1) CGI::escape('foo_&_bar')
"foo_%26_bar"

发生了什么事,我该如何解决这个问题?(就是比 更好的东西gsub('&', '%26')。)

4

2 回答 2

17

我无法告诉你更好的处理方式——但我可以解释为什么会这样。

与号不是 URL 的无效字符。否则你会遇到问题:“ http://host/pages/foo?bar=baz&style=foo_style ”或其他什么。

编辑:深入挖掘源代码,看起来 Rails 仅在参数上使用 CGI.escape。

帮助器,url-generators 使用 url_for (在幕后),它最终调用:http://apidock.com/rails/ActionController/Routing/Route/generate 它调用源代码的私有方法深处的东西.. . 但最终最终调用 CGI.escape (首先查看 actionpack/lib/action_controller/routing/route.rb 然后在 actionpack/lib/action_controller/routing/segments.rb 中)

最终结果是,在 url 本身上,rails 使用 URI.escape - 值得注意的是,它根本不更新 & 符号:

>> CGI.escape('/my_foo_&_bar')
=> "%2Fmy_foo_%26_bar"
>> URI.escape('/my_foo_&_bar')
=> "/my_foo_&_bar"

如果不向 Rails 团队提出实际的功能请求,目前您无能为力。

...除非您可以选择不在 URL 中使用 & 符号,否则您始终可以自己为所有 URL 使用 gsub:

def my_clean_url(the_url)
   return the_url.gsub(/&/,'_')
end
>> my_clean_url('/my_foo_&_bar')
=> "/my_foo___bar"

page_url(my_clean_url('/my_foo_&_bar'))
于 2011-03-22T16:34:49.087 回答
11

对于那些试图只编码除 az、AZ、0-9 和下划线以外的任何内容的人:

URI.encode(string, /\W/)

假设您有一些可能包含与符号的内容,并且您想将此内容用作链接的body参数mailto:如果没有/\W/,则与符号(这是一个安全的 URI 字符)将不会被编码,因此会部分破坏链接。

于 2016-09-22T17:10:36.517 回答