Ruby on rails Rails Rack::缓存和中间件基于移动设备的头重定向

Ruby on rails Rails Rack::缓存和中间件基于移动设备的头重定向,ruby-on-rails,caching,rack,Ruby On Rails,Caching,Rack,如何编写机架中间件,根据用户代理字符串将用户重定向到不同的子域?我需要在rails应用程序中的Rack::Cache之前运行它,我还希望这个中间件能够检测cookie的存在。 我们在子域(“m.domain.com”)上有一个移动优化站点 如果访问者访问“www.domain.com”,我们将用户代理字符串识别为移动设备,并且他们还没有表示他们喜欢完整站点的cookie集,那么我们将他们重定向到移动子域。这目前是在我们的ApplicationController中的before筛选器中完成的

如何编写机架中间件,根据用户代理字符串将用户重定向到不同的子域?我需要在rails应用程序中的Rack::Cache之前运行它,我还希望这个中间件能够检测cookie的存在。

  • 我们在子域(“m.domain.com”)上有一个移动优化站点
  • 如果访问者访问“www.domain.com”,我们将用户代理字符串识别为移动设备,并且他们还没有表示他们喜欢完整站点的cookie集,那么我们将他们重定向到移动子域。这目前是在我们的ApplicationController中的before筛选器中完成的
目前,如果我们在rails应用程序中为主页设置缓存头,Rack::cache会缓存主页,但当移动用户访问主“www”域时,Rack::cache会提供页面的缓存版本,而不会访问rails应用程序的其余部分,因此我们的移动重定向永远不会执行

似乎我必须将我们的移动重定向解决方案转移到在Rack::Cache之前执行的中间件中。对于上下文,以下是我们的过滤器在ApplicationController中的外观:

before_filter :set_mobile_preferences
before_filter :redirect_to_mobile_if_applicable  

def set_mobile_preferences
  if params[:mobile_site]
    cookies.delete(:prefer_web)
  elsif params[:full_site]
    cookies.permanent[:prefer_web] = 1
    redirect_to_full_site if mobile_request?
  end
end

# before filter
def redirect_to_mobile_if_applicable
  if mobile_device? && !mobile_request? && !prefers_full_site?
    new_url = request.protocol + domain_prefixes[:mobile] + '.' +
              request.host_with_port.gsub(/^#{domain_prefixes[:web]}?\./, '') + 
              request.fullpath
    redirect_to new_url and return
  end
end
是否有人拥有缓存页面和将移动用户重定向到备用域的经验?将此重定向移动到缓存层之前的中间件似乎是正确的解决方案吗

任何提示,链接,建议都将不胜感激。谢谢


更新:也许我可以使用
Vary:User-Agent
标题来帮助解决缓存问题?但是,我担心如果我这样做,缓存将填满同一页面的多个副本,因为浏览器发送的用户代理字符串有数百种变化。

因此,我决定编写我们自己的中间件来检测移动用户代理字符串,重定向到子域,并且还检测站点首选项cookie的存在,因此我们仅在用户未另行指定的情况下基于用户代理重定向用户。我在机架堆栈中将其向上移动,使其在Rack::Cache之前执行,这似乎解决了我们的问题。您可以在此处查看源代码: