Rails url helper 不编码 & 符号

发布于 2024-10-06 22:09:04 字数 759 浏览 5 评论 0原文

因此,我尝试使用 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') 更好的东西,就是这样。)

So I'm trying to use a Rails URL helper (page_url) to create URLs that contain special characters, including ampersands. Most cases work like you'd expect them to:

(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"

But for some odd reason, ampersands are not escaped:

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

And if I pre-escape them, they get corrupted:

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

CGI::escape, on the other hand, escapes them fine:

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

What's going on, and how do I work around this? (With something nicer than gsub('&', '%26'), that is.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暖风昔人 2024-10-13 22:09:04

我无法告诉你更好的处理方法 - 但我可以解释为什么会发生这种情况。

& 符号对于 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-methods 深处的东西......但最终最终调用了 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'))

I can't tell you a nicer way to deal with it - but I can explain why it's happening.

Ampersands are not invalid characters for a URL. Otherwise you'd have problems with: "http://host/pages/foo?bar=baz&style=foo_style" or whatever.

Edit:
Digging deeper into the source code, it looks like Rails uses CGI.escape only on parameters.

The helper, url-generators use url_for (under the covers), which eventually calls: http://apidock.com/rails/ActionController/Routing/Route/generate
Which calls stuff deep in the sprivate-methods of the source code... but eventually ends up calling CGI.escape
(first look in actionpack/lib/action_controller/routing/route.rb then in actionpack/lib/action_controller/routing/segments.rb )

End result is that on the url itself, rails uses URI.escape - which notably does not update ampersands at all:

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

There's currently nothing you can do about this without putting an actual feature-request onto the rails team.

...unless you have the option to choose not to use ampersands in your URLs
You can always gsub them out yourself for all URLs:

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'))
失与倦" 2024-10-13 22:09:04

对于所有尝试编码除 az、AZ、0-9 和下划线之外的任何内容的人:

URI.encode(string, /\W/)

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

For all those who are trying to just encode anything other than a-z, A-Z, 0-9 and underscore:

URI.encode(string, /\W/)

Say you have some content which may contain e.g. ampersands and you want to use this content as body parameter for a mailto link: Without /\W/, the ampersand (which is a safe URI character) would not be encoded and therefore partially break the link.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文