Rails url helper不编码&符号

时间:2010-12-09 02:46:10

标签: ruby-on-rails helper url-encoding

所以我正在尝试使用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')好的东西,就是。)

2 个答案:

答案 0 :(得分:14)

我不能告诉你一个更好的方法来解决它 - 但我可以解释它为什么会发生。

“&”不是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 在源代码的sprivate方法中深入调用的东西......但最终最终调用了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团队,您目前无法做到这一点。

...除非您可以选择不在网址中使用&符号 您可以随时自行查找所有网址:

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'))

答案 1 :(得分:9)

对于那些试图编码除a-z,A-Z,0-9和下划线以外的任何东西的人:

URI.encode(string, /\W/)

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