将非www请求重定向到Rails中的www url

简单的问题,但似乎无法找到一些快速谷歌搜索的答案。 直接执行此操作的Rails方法是什么( http://x.com/abc > http://www.x.com/abc )。 一个before_filter?

理想情况下,您可以在Web服务器(Apache,nginx等)配置中执行此操作,以便请求甚至根本不触及Rails。

将以下before_filter添加到ApplicationController

 class ApplicationController < ActionController::Base before_filter :add_www_subdomain private def add_www_subdomain unless /^www/.match(request.host) redirect_to("#{request.protocol}x.com#{request.request_uri}", :status => 301) end end end 

如果您确实想使用Apache进行重定向,可以使用:

 RewriteEngine on RewriteCond %{HTTP_HOST} !^www\.x\.com [NC] RewriteRule ^(.*)$ http://www.x.com/$1 [R=301,L] 

虽然John的答案非常好,但如果你使用的是Rails> = 2.3,我建议创建一个新的Metal。 Rails金属效率更高,性能更好。

 $ ruby script/generate metal NotWwwToWww 

然后打开文件并粘贴以下代码。

 # Allow the metal piece to run in isolation require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails) class NotWwwToWww def self.call(env) if env["HTTP_HOST"] != 'www.example.org' [301, {"Content-Type" => "text/html", "Location" => "www.#{env["HTTP_HOST"]}"}, ["Redirecting..."]] else [404, {"Content-Type" => "text/html"}, ["Not Found"]] end end end 

当然,您可以进一步定制金属。

如果你想使用Apache, 这里有一些配置 。

对于导轨4,使用它 –

  before_filter :add_www_subdomain private def add_www_subdomain unless /^www/.match(request.host) redirect_to("#{request.protocol}www.#{request.host_with_port}",status: 301) end end 

有一个更好的Rails 3方式 – 把它放在你的routes.rb文件中:

  constraints(:host => "example.com") do # Won't match root path without brackets around "*x". (using Rails 3.0.3) match "(*x)" => redirect { |params, request| URI.parse(request.url).tap { |x| x.host = "www.example.com" }.to_s } end 

更新

以下是如何使其与域无关:

  constraints(subdomain: '') do match "(*x)" => redirect do |params, request| URI.parse(request.url).tap { |x| x.host = "www.#{x.host}" }.to_s end end 

我在尝试实现相反的时候找到了这篇文章(www到根域重定向)。 所以我写了一段代码, 将所有页面从www重定向到根域 。

您可以尝试以下代码 –

 location / { if ($http_host ~* "^example.com"){ rewrite ^(.*)$ http://www.example.com$1 redirect; } }