How to redirect without www using Rails 3 / Rack?

倖福魔咒の 提交于 2019-11-28 16:22:01

in Rails 4 removing www. from any URL whilst maintaining the pathname can be achieved simply by using:

# config/routes.rb

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

In contrast, adding www. to the beginning of any URL that doesn't already have it can be achieved by:

# config/routes.rb

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

There's a better approach if you're using Rails 3. Just take advantage of the routing awesomeness.

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

I really like using the Rails Router for such things. Previous answers were good, but I wanted something general purpose I can use for any url that starts with "www".

I think this is a good solution:

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

Take a look at this middleware, it should do precisely what you want:

http://github.com/iSabanin/www_ditcher

Let me know if that worked for you.

A one-line version of Duke's solution. Just add to the top of routes.rb

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

In 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

If you want to redirect from the top-level domain (TLD) to the www subdomain, use this code:

constraints :subdomain => '' do
  match '(*any)' => redirect { |p, req| req.url.sub('//', '//www.') }
end

Note: This code the use of sub, not gsub, because sub replaces the first occurrence of the double-slashes where gsub would replace all double-slashes.

For Rails 4 the above solutions have to be appended with the Verb construction e.g. via: [:get, :post]. Duke's solution becomes:

  constraints(:host => /^www\./) do
    match "(*x)" => redirect { |params, request|
      URI.parse(request.url).tap {|url| url.host.sub!('www.', '') }.to_s
    }, via: [:get, :post]
  end

Nothing wrong with the approaches above, but there are also a couple of gems that provide Rack middleware to do this.

I like the way that they keep this behaviour separate from the app itself, but it's not a particularly strong argument either way. I also use middleware to do this when working with Sinatra, so prefer to use a technique that I can use on apps built from Rails and/or Sinatra (I often run Nesta embedded in Rails).

Anyway, here they are:

The first is simpler (and the one I've been using) while the second offers a couple more features (that I'm yet to need, but appreciate).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!