我需要处理像/: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 认为.bina.b是格式扩展。
有没有办法让 Rails 表现得明智并检查解码:slug后的约束,还是我必须放松约束或手动完成?