我需要处理像/:slug
. 蛞蝓在其他地方被限制以匹配:
\A[\p{Alnum}_.-]{3,}\z
明显的路线:
get '/:slug' => '...', :constraints => { :slug => /[\p{Alnum}_.-]{3,}/ }
get '/:slug' => '...', :slug => /[\p{Alnum}_.-]{3,}/
使用 ASCII URL 可以正常工作/mu-is-too-short
,/where.is.pancakes.house
但是当 URL 为/µ-is-too-short
. 浏览器将其发送到服务器:
/%C2%B5-is-too-short
并且 Rails 正在尝试%C2%B5-is-too-short
根据:slug
约束检查编码并失败,因为%
不是\p{Alnum}
.
我想出了两个kludges:
get '/:slug' => '...', :slug => /.{3,}/
get '/:slug' => '...', :slug => /[^\/]+/, :constraints => lambda { |r| r.path_parameters[:slug].to_s =~ /\A[\p{Alnum}_.-]{3,}\z/ }
需要第二:slug => /[^\/]+/
个 in 以防止 Rails 认为.b
ina.b
是格式扩展。
有没有办法让 Rails 表现得明智并检查解码:slug
后的约束,还是我必须放松约束或手动完成?