【问题标题】:Rails url helper not encoding ampersandsRails url helper 不编码 & 符号
【发布时间】:2011-05-22 14:49:11
【问题描述】:

所以我尝试使用 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') 更好的东西。)

【问题讨论】:

  • 嗯.. 我实际上找不到专门称为 page_url 的 rails 助手(在 apidock 网站上查看)-您确定这是正确的方法名称吗?你的意思是 url_for 吗?
  • 我有一个名为“page”的 ActiveRecord,它的 _url 助手是自动创建的。
  • 啊——对。你的描述中没有体现出来:)
  • 在深入研究源代码后,在我的答案中添加了更多内容。

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


【解决方案1】:

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

URI.encode(string, /\W/)

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

【讨论】:

    【解决方案2】:

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

    与号不是 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 中使用与号 您始终可以自己 gsub 获取所有 URL:

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

    【讨论】:

    • 问题是底层(非 Ruby)应用程序将 & 用作普通字符,但许多 URL 解析器将其视为参数分隔符,并在看到它时将 URL 截断。对其进行编码可确保其完好无损。
    • 很好的答案。谢谢塔林!我做了一个快速实验,用一个简单的 Car 资源创建了一个新的 Rails 3 项目,并通过它运行 ascii 字符,以查看当我调用 car_path(some_ascii_char) 时 Rails 编码了什么。 IE。 (1..256).map {|汽车| app.car_path(car.chr)} 我发现除了! $ % & ' - , + * ( ) / : ; = @ 。 _ ~ 因此只有 % / ? & 可能有问题,需要手动编码。
    • 不如直接调用:CGI.unescape(page_url('foo_%_bar', :host => 'host'))
    猜你喜欢
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多