所以我正在尝试使用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')
好的东西,就是。)
答案 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字符)将不会被编码,因此会部分破坏链接。