Rails 关于 Rails 中的路由问题

ecloud · 2018年01月11日 · 最后由 liuminhan 回复于 2018年01月11日 · 1548 次阅读

我再 routers 中写下如下的路由,然后 POST 地址 /weixin,出现错误 No route matches [POST] "/weixin"

scope :path => '/weixin', :via => :post do
        match "/", :to => 'weixin#method_text', :constraints => lambda{|request| Nokogiri::XML(request.body.read).xpath('//MsgType').text == 'text'}
        match "/", :to => 'weixin#method_image', :constraints => lambda{|request| Nokogiri::XML(request.body.read).xpath('//MsgType').text == 'image'}
        match "/", :to => 'weixin#method_location', :constraints => lambda{|request| Nokogiri::XML(request.body.read).xpath('//MsgType').text == 'location'}
        match "/", :to => 'weixin#method_event', :constraints => lambda{|request| Nokogiri::XML(request.body.read).xpath('//MsgType').text == 'event'}
end

但是我这样写是可以的

scope :path => '/weixin', :via => :post do
        match "/", :to => 'weixin#method_event', :constraints => lambda{|request| Nokogiri::XML(request.body.read).xpath('//MsgType').text == 'event'}
end

不太懂是什么原因,求教各位

这路由看得头疼..

@msl12 路由有点长,根据微信 POST 过来的 MsgType 选择方法。

@msl12 我刚才又改变了下,只有匹配第一个才能成功,不知道为什么。

@msl12 找到原因了,每次 read 后需要 seek 0。

ecloud 回复

成功了?

msl12 回复

是的。因为每次 read 导致 position 指向最后,后面的 read 就读不到内容了

7 楼 已删除

我刚才试了一下,后面的路由还是匹配错误,应该是 Nokogiri::XML 中还是使用 read

我这么写的可以,加个解析 xml 的 gem

scope :path => "/weixin", :via => :post do
   match "/", :to => 'weixin#method_text', :constraints => lambda { |request| request.params[:xml][:MsgType] == 'text' }
   match "/", :to => 'weixin#method_image', :constraints => lambda { |request| request.params[:xml][:MsgType] == 'image' }
   match "/", :to => "weixin#method_location",:constraints => lambda { |request| request.params[:xml][:MsgType] == 'location' }
   match "/", :to => "weixin#method_event",:constraints => lambda { |request| request.params[:xml][:MsgType] == 'event'}
end
gem actionpack-xml_parser, ~> 1.0.1
liuminhan 回复

你应该使用了 actionpack-xml_parser 这个 gem 吧,我试了下这个 Gem,按照教程没法使用。

@liuminhan 能给我一份使用教程吗?github 上也没找到可用的 doc

ecloud 回复

config.middleware.insert_after ActionDispatch::ParamsParser, ActionDispatch::XmlParamsParser

这个加了没?

@liuminhan 加了这一句没法启动了

uninitialized constant ActionDispatch::XmlParamsParser (NameError)

好吧,目前我用的最笨的办法,每次 read 前使用 seek 0,如果谁有更好的办法请告诉我,感谢💯

ecloud 回复

我之前是用的 4.x 的 rails 版本

@liuminhan 我用的是 5.x 的 rails,可能版本太新了

试试 request.raw_post

Rei 回复

完美解决,感谢/:strong

liuminhan 回复

提醒:xml parser 以前出过远程执行漏洞,后来 rails 就干脆剥离了,目前维护热度肯定不高,为了安全最好别用。

Rei 回复

就是微信的时候用过一次,后来就没有遇到过这样的场景了,多谢提醒

ecloud 关闭了讨论。 01月12日 11:19
需要 登录 后方可回复, 如果你还没有账号请 注册新账号