如何使用Rails 3/Rack在没有www的情况下重定向?

mač*_*ček 37 seo redirect rack ruby-on-rails ruby-on-rails-3

我知道有很多问题可以解答这个问题.我熟悉.htaccessnginx.conf方法,但我无法访问heroku上的这种传统配置方法.

Simone Carletti给出了这个利用Rails 2.x Metals的答案,但我使用的是Rails 3,这是不兼容的. 将非www请求重定向到Rails中的www URL

请注意:

我不是before_filter在我的ApplicationController中寻找一个简单的东西.我想完成类似于Simone的重写.我认为这至少是网络服务器或像Rack这样的中间件的工作,所以我想把这一点留在实际的应用程序代码中.

目标

redirect                to                  status
----------------------------------------------------
www.foo.com             foo.com             301
www.foo.com/whatever    foo.com/whatever    301
Run Code Online (Sandbox Code Playgroud)

只有主机匹配/^www\./才能重定向.应忽略所有其他请求.

小智 51

Rails 4删除www.从任何URL,同时保持路径名可以简单地通过使用:

# config/routes.rb

constraints subdomain: 'www' do
  get ':any', to: redirect(subdomain: nil, path: '/%{any}'), any: /.*/
end
Run Code Online (Sandbox Code Playgroud)

相反,添加www.到任何尚未拥有它的URL的开头可以通过以下方式实现:

# config/routes.rb

constraints subdomain: false do
  get ':any', to: redirect(subdomain: 'www', path: '/%{any}'), any: /.*/
end
Run Code Online (Sandbox Code Playgroud)

  • 我不确定它是否是我正在做的事情但是当使用`constraints subdomain:false`时,它实际上由于某种原因进行了两次重定向并最终在`www.www.localhost:3000`中.在浏览器中我可以看到它重定向`localhost:3000` =>`www.localhost:3000` =>`www.www.localhost:3000` (2认同)
  • 它无法工作的原因是因为路由器检查TLD和域名,使得`localhost`和`www.localhost`没有子域. (2认同)

Sea*_*eld 13

如果您正在使用Rails 3,那么有一种更好的方法.只需利用路由功能即可.

Foo::Application.routes.draw do
  constraints(:host => /^example.com/) do
    root :to => redirect("http://www.example.com")
    match '/*path', :to => redirect {|params| "http://www.example.com/#{params[:path]}"}
  end
end
Run Code Online (Sandbox Code Playgroud)


Duk*_*uke 12

我真的很喜欢使用Rails路由器来做这些事情.以前的答案很好,但我想要一些通用的用途,我可以使用任何以"www"开头的网址.

我认为这是一个很好的解决方案:

constraints(:host => /^www\./) do
  match "(*x)" => redirect { |params, request|
    URI.parse(request.url).tap {|url| url.host.sub!('www.', '') }.to_s
  }
end
Run Code Online (Sandbox Code Playgroud)


Ily*_*nin 7

看看这个中间件,它应该正是你想要的:

http://github.com/iSabanin/www_ditcher

如果这对您有用,请告诉我.


Wil*_*ler 7

杜克解决方案的单行版本.只需添加到routes.rb的顶部即可

match '(*any)' => redirect { |p, req| req.url.sub('www.', '') }, :constraints => { :host => /^www\./ }
Run Code Online (Sandbox Code Playgroud)


Vik*_*ary 6

在Rails 3中

#config/routes.rb
Example::Application.routes.draw do
  constraints(:host => "www.example.net") do
    match "(*x)" => redirect { |params, request|
      URI.parse(request.url).tap { |x| x.host = "example.net" }.to_s
    }
  end
  # .... 
  # .. more routes ..
  # ....
end
Run Code Online (Sandbox Code Playgroud)