【问题标题】:Rails Routing Constraints and UTF-8Rails 路由约束和 UTF-8
【发布时间】:2013-09-25 04:31:54
【问题描述】:

我需要处理像/:slug 这样的路由。蛞蝓被限制在其他地方以匹配:

\A[\p{Alnum}_.-]{3,}\z

明显的路线:

get '/:slug' => '...', :constraints => { :slug => /[\p{Alnum}_.-]{3,}/ }
get '/:slug' => '...', :slug => /[\p{Alnum}_.-]{3,}/

使用/mu-is-too-short/where.is.pancakes.house 等ASCII URL 可以正常工作,但是当URL 为/µ-is-too-short 时,一切都会崩溃。浏览器将其发送到服务器:

/%C2%B5-is-too-short

Rails 正在尝试根据:slug 约束检查编码的%C2%B5-is-too-short 并失败,因为% 不是\p{Alnum}

我想出了两个组合:

get '/:slug' => '...', :slug => /.{3,}/
get '/:slug' => '...', :slug => /[^\/]+/, :constraints => lambda { |r| r.path_parameters[:slug].to_s =~ /\A[\p{Alnum}_.-]{3,}\z/ }

第二个中的:slug => /[^\/]+/ 用于防止Rails 认为a.b 中的.b 是格式扩展。

有没有办法让 Rails 表现得合理,并根据约束检查解码的:slug,还是我必须放松约束或手动执行?

【问题讨论】:

  • 所以问题基本上是与约束匹配的参数没有被url解码,对吗?
  • @MichaelSzyndel:是的。 Rails 确实在r.path_parameters[:slug] 中有解码值,但它似乎没有将它用于约束检查。我只需要在第二个中添加:slug => /[^\/]+/ 即可让Rails 正确提取带有. 的slug,这暗示了一些关于解析顺序的事情。
  • 看你的问题很明显,但我只是想清除它。我尝试查看 Rails 路由代码并放弃了。
  • 我正在考虑制作一个匹配所有允许的字母/符号的正则表达式,但在 utf-8 空间中太复杂了。黑名单看起来也不是很有希望。
  • 你可能对 Rails 5 感兴趣,它接受路径名、文件名等中的 utf-8 字符。如果没有,则尝试查找 mew 字符的 HEX 转换,而 ruby​​ 会处理它

标签: ruby-on-rails ruby-on-rails-3 utf-8 routing


【解决方案1】:

您可以使用 lambda 作为约束,这样可以更改编码(来自 http://www.intridea.com/blog/2011/2/21/use-lambdas-for-rails3-route-constraints):

scope :constraints => lambda{|req| !req.session[:user_id].blank? } do
  # all my logged in routes
end

【讨论】:

  • 这只是我的第二个伪装 (:constraints => lambda { |r| ... })。我正在寻找一种方法来说服 Rails 做出明智的行为,并根据它已经拥有的解码路径检查约束。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
  • 2014-04-25
  • 1970-01-01
  • 2012-09-07
相关资源
最近更新 更多