3

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

  • 我们在子域(“m.domain.com”)上有一个移动优化网站。
  • 如果访问者访问“www.domain.com”并且我们将用户代理字符串识别为移动设备,并且他们还没有表明他们更喜欢完整站点的 cookie 集,那么我们会将他们重定向到移动子域。这目前在我们的 ApplicationController 中的前置过滤器中完成。

目前,如果我们在 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标题来帮助解决缓存问题?但是,我担心如果我这样做,那么缓存将被同一页面的多个副本填满,因为浏览器发送的用户代理字符串有数百种变体。

4

1 回答 1

4

所以,我决定编写我们自己的中间件来检测移动用户代理字符串,重定向到子域,并检测站点偏好 cookie 的存在,因此我们仅基于用户代理重定向用户,如果他们没有另有规定。我将它移到了 Rack 堆栈中,因此它在 Rack::Cache 之前执行,这似乎解决了我们的问题。你可以在这里查看源代码:https ://gist.github.com/3630760

于 2012-09-05T04:56:12.780 回答