ruby-on-rails 如何使用gem rack-rewrite到301重定向从裸域到www域的完整URL

mxg2im7a  于 2023-03-09  发布在  Ruby
关注(0)|答案(4)|浏览(156)

我有一个Rails 2.3.2应用程序托管在Heroku上。
naked域名和www子域是几年前添加的,它们都对搜索引擎有一定的权威性。
然而问题是,搜索引擎看到的内容是重复的,所以我想做301重定向从裸域到www子域。
我问过Zerigo DNS,我是否可以通过他们的平台来完成这项工作,他们说不行,我必须在Heroku这边完成。Heroku不允许访问服务器,所以我需要一些Rack中间件来执行这项工作。
根据此答案here,gem机架重写可以执行此操作。
然而,我真的是一个NOOB关于这一点,我不知道如何设置这一点,使任何网址从裸域将301重定向到www子域。
示例:
example.com/products/12 名称www.example.com/products/12
我目前在应用程序控制器中做了如下错误的事情:

before_filter :ensure_domain

protected 

  def ensure_domain
      app_domain = "www.example.com"
      naked_domain = "example.com"
      page_path = request.fullpath
    if request.env['HTTP_HOST'] == naked_domain  && RAILS_ENV == 'production'
      #HTTP 301 is a permanent redirect
        redirect_to "http://#{app_domain}#{page_path}", :status => 301
    end
  end

这工作,但我知道我应该这样做的机架中间件。
有人能告诉我如何设置这与机架重写宝石?
我已将以下内容添加到application_controller.rb文件中:

config.middleware.insert_before(Rack::Lock, Rack::Rewrite) do
 r301 %r{.*}, 'http://www.example.com$&', :if => Proc.new {|rack_env|
  rack_env['SERVER_NAME'] != 'www.example.com'
}
end

这会产生以下错误:
名称错误(ApplicationController:类的未定义局部变量或方法“config”):
你知道我该怎么做吗?

9nvpjoqh

9nvpjoqh1#

您也可以使用rack-host-redirect gem。添加到宝石文件:

gem 'rack-host-redirect'

config/environments/production.rb中:

config.middleware.use Rack::HostRedirect, {
  'yourdomain.com' => 'www.yourdomain.com'
}

使用此配置,所有到yourdomain.com的请求将被重定向301到www.yourdomain.com

kuhbmx9i

kuhbmx9i2#

example.com/products/12 名称www.example.com/products/12
为了解决Heroku的这个问题,我必须正确设置我的域名托管服务器。您要查找的是名为转发的服务器。接下来,您要启用“保留相对路径”选项。
因此,请寻找:
1.重定向类型:301例永久性
1.转发设置:仅向前
1.保留相对路径
这一切都应该在您的域名注册商的水平。

gcuhipw9

gcuhipw93#

根据the gem's README,您需要将以下内容添加到应用程序的config/application.rb中:

config.middleware.insert_before(Rack::Lock, Rack::Rewrite) do
  moved_permanently /.*/, 'http://www.example.com$&', if: ->(env){env['SERVER_NAME'] != 'www.example.com'}
end

我已经更新了示例代码,并在Rails 3应用程序上测试了它。
moved_permanently方法的参数为:

  1. /.*/是匹配任何请求路径和url参数的正则表达式,因此匹配站点上的任何页面。
  2. 'http://www.example.com$&'是页面的新的完整URL(重定向后),它有正确的域名和原始请求路径-$&符号表示“第一个参数匹配的任何内容”,它匹配所有内容。
  3. if: ->(env){env['SERVER_NAME'] != 'www.example.com'}是此重写规则的选项散列。在本例中,它只有一个名为if的选项。该选项的值是一个lambda函数:->(env){env['SERVER_NAME'] != 'www.example.com'} .
    gem将为每个请求调用这个lambda,它将把所有环境变量的哈希值作为参数传递给它(我调用了参数env,但名称可以是任意的)。
    lambda从中读取客户端用来向站点发出请求的域名:env['SERVER_NAME']。它检查域是否正确。
  • 如果域不正确,则返回true。在这种情况下,并且仅在这种情况下,gem将重写URL并向客户机返回状态301。
  • 如果域是正确的,它返回false,在这种情况下,将不采取任何操作,请求将“通过”应用程序(到其他中间件)。
v9tzhpje

v9tzhpje4#

我发现我在使用这个宝石的时候遇到了两个问题。
第一个问题是,我将重定向代码放在Application_Controller中,而不是放在config.ru文件中。
第二个问题是我使用的代码不正确。
下面是我放在www.example.com文件中的代码config.ru:

if RAILS_ENV =='production'
    use Rack::Rewrite do
        r301 %r{.*}, 'http://www.example.com$&', :if => Proc.new {|rack_env|
        rack_env['SERVER_NAME'] != 'www.example.com'
        }
    end
end

相关问题