Rails 路由约束和 UTF-8
Posted
技术标签:
【中文标题】Rails 路由约束和 UTF-8【英文标题】:Rails Routing Constraints and UTF-8 【发布时间】:2013-09-25 04:31:54 【问题描述】:我需要处理像/:slug
这样的路由。蛞蝓被限制在其他地方以匹配:
\A[\pAlnum_.-]3,\z
明显的路线:
get '/:slug' => '...', :constraints => :slug => /[\pAlnum_.-]3,/
get '/:slug' => '...', :slug => /[\pAlnum_.-]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
并失败,因为%
不是\pAlnum
。
我想出了两个组合:
get '/:slug' => '...', :slug => /.3,/
get '/:slug' => '...', :slug => /[^\/]+/, :constraints => lambda |r| r.path_parameters[:slug].to_s =~ /\A[\pAlnum_.-]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 会处理它
【参考方案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 做出明智的行为,并根据它已经拥有的解码路径检查约束。以上是关于Rails 路由约束和 UTF-8的主要内容,如果未能解决你的问题,请参考以下文章