Ruby on rails 如何使用gem rack rewrite将完整URL从裸域重定向到www域
我在Heroku上有一个Rails 2.3.2应用程序 裸域和www子域是在几年前添加的,它们对搜索引擎都有一定的权威 然而问题是,搜索引擎看到的内容是重复的,所以我想做301重定向从裸域到www子域 我问过Zerigo DNS我是否可以通过他们的平台来做这件事,他们说不行,我必须站在Heroku一边。Heroku不允许访问服务器,因此我需要一些机架中间件来执行此操作 根据这个答案,gem机架重写可以做到这一点 然而,我真的是一个NOOB关于这一点,我不知道如何设置这一点,使任何网址从裸域将301重定向到www子域 例如: example.com/products/12=>www.example.com/products/12 我目前在应用程序控制器中做了如下错误操作:Ruby on rails 如何使用gem rack rewrite将完整URL从裸域重定向到www域,ruby-on-rails,rack-rewrite,Ruby On Rails,Rack Rewrite,我在Heroku上有一个Rails 2.3.2应用程序 裸域和www子域是在几年前添加的,它们对搜索引擎都有一定的权威 然而问题是,搜索引擎看到的内容是重复的,所以我想做301重定向从裸域到www子域 我问过Zerigo DNS我是否可以通过他们的平台来做这件事,他们说不行,我必须站在Heroku一边。Heroku不允许访问服务器,因此我需要一些机架中间件来执行此操作 根据这个答案,gem机架重写可以做到这一点 然而,我真的是一个NOOB关于这一点,我不知道如何设置这一点,使任何网址从裸域将30
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
这是可行的,但我知道我应该在机架中间件中这样做
有人能告诉我如何用rack rewrite gem设置这个吗
我已将以下内容添加到我的应用程序\u 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
这将产生以下错误:
NameError(ApplicationController:Class的未定义局部变量或方法“config”):
关于如何使此设置正常工作,您有什么想法吗?根据,您需要将以下内容添加到应用程序的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
config.middleware.use Rack::HostRedirect, {
'yourdomain.com' => 'www.yourdomain.com'
}
我已经更新了示例代码,并在Rails 3应用程序上进行了测试
moved\u永久
方法的参数为:
/.*/
是一个正则表达式,它匹配任何请求路径和url参数,因此匹配站点上的任何页面'http://www.example.com$&'
是页面的新完整URL(重定向后)。它有正确的域名和原始请求路径-$&
符号表示“第一个参数匹配的任何内容”,它匹配所有内容if:->(env){env['SERVER_NAME']!='www.example.com'}
是此重写规则的选项哈希。在这种情况下,它只有一个名为if
的选项。该选项的值是一个lambda函数:->(env){env['SERVER\u NAME']!='www.example.com'}
李>
gem将为每个请求调用这个lambda。它将把所有环境变量的散列作为参数传递给它。(我调用了参数env
,但名称可以是任意名称。)
lambda从中读取客户端用于向站点发出请求的域名:env['SERVER\u name']
。它检查域是否正确
- 如果域不正确,则返回
。在这种情况下,并且仅在这种情况下,gem将重写URL并将状态301返回给客户端李>true
- 如果域是正确的,则返回
。在这种情况下,将不采取任何操作,请求将“通过”应用程序(其他中间件)false
这一切都应该可以在您的域名注册的水平 我发现我在使用这个gem时遇到了两个问题 首先,我将重定向代码放在应用程序控制器中,而不是放在congig.ru文件中 第二个原因是我使用的代码不正确 下面是我放在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
你也可以使用gem。添加到文件:
gem 'rack-host-redirect'
在config/environments/production.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
config.middleware.use Rack::HostRedirect, {
'yourdomain.com' => 'www.yourdomain.com'
}
通过此配置,对
yourdomain.com
的所有请求都将被301重定向到www.yourdomain.com
谢谢Ilya。我想知道这是否会重定向所有URL,而不仅仅是基本主机。因此,example.com/products/34至www.example.com/products/34Yes。我添加了参数解释。希望这有帮助!我联系了我的DNS主机,他们没有这个选项。这就是为什么我要用rack-rewrite尝试这个路径。它们有一个前进选项,但没有“保持相对路径”。如果RAILS\u ENV=='production'条件,您可以将此代码移动到config/environments/production.rb
。您应该将生产配置放在config/environments/production.rb
我添加的if RAILS_ENV='production'中,这样重定向就不会在本地主机上发生。我将此代码放在config.ru中,因为这是文档为这个gem声明的内容。当我把它放在production.rb文件中时,我也遇到了错误