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

New*_*ewy 10 ruby-on-rails

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

Joh*_*ley 18

理想情况下,您可以在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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 对于上面代码中的 301 重定向,您需要包含状态。否则它只是一个 302 临时重定向。redirect_to("#{request.protocol}x.com#{request.request_uri}", :status=&gt;301) (2认同)

Mas*_*man 8

对于导轨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
Run Code Online (Sandbox Code Playgroud)

  • 这会丢弃URL路径 (2认同)

Sim*_*tti 7

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

$ ruby script/generate metal NotWwwToWww
Run Code Online (Sandbox Code Playgroud)

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

# 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
Run Code Online (Sandbox Code Playgroud)

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

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