web-dev-qa-db-ja.com

Rails 3 / Rackを使用してwwwなしでリダイレクトするにはどうすればよいですか?

これに答える質問がたくさんあることを理解しています。私は.htaccessメソッドとnginx.confメソッドに精通していますが、Herokuでこのような従来の構成メソッドにアクセスすることはできません。

Simone Carletti Rails 2.x Metals、しかし私はRails 3そしてこれは互換性がありません:

www以外のリクエストをRuby on RailsのwwwURLにリダイレクトする

ご注意ください:

ApplicationControllerで単純なbefore_filterを探していません。シモーネと同じような書き直しをしたいです。これは少なくともRackのようなWebサーバーやミドルウェアの仕事だと思うので、実際のアプリケーションコードからこのビットを除外したいと思います。

ゴール

redirect                to                  status
----------------------------------------------------
www.foo.com             foo.com             301
www.foo.com/whatever    foo.com/whatever    301

/^www\./に一致するホストのみをリダイレクトする必要があります。他のすべての要求は無視する必要があります。

36
maček

Ruby on Rails 4では、パス名を維持しながら任意のURLからwww。を削除するには、次のコマンドを使用するだけです。

# config/routes.rb

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

対照的に、wwwを追加します。まだURLを持っていないURLの先頭までは、次の方法で実現できます。

# config/routes.rb

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

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
13
Sean Schofield

Railsルーターをそのようなものに使うのが本当に好きです。以前の答えは良かったのですが、「www」で始まる任意のURLに使用できる汎用的なものが欲しかったのです。

これは良い解決策だと思います:

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

デュークのソリューションの1行バージョン。ルートの先頭に追加するだけです。rb

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

このミドルウェアを見てください、それはあなたが望むことを正確に行うはずです:

http://github.com/iSabanin/www_ditcher

それがあなたのために働いたかどうか私に知らせてください。

7
Ilya Sabanin

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
6

トップレベルドメイン(TLD)からwwwサブドメインにリダイレクトする場合は、次のコードを使用します。

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

注:このコードでは、gsubではなくsubを使用します。これは、gsubがすべてのダブルスラッシュを置き換える最初のダブルスラッシュをsubが置き換えるためです。

3
scarver2

Rails 4の場合、上記のソリューションに動詞構文を追加する必要があります。例:via: [:get, :post]。デュークの解決策は次のようになります。

  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
3
Jessie Dedecker

上記のアプローチに問題はありませんが、これを行うためのRackミドルウェアを提供するgemもいくつかあります。

私は彼らがこの振る舞いをアプリ自体から分離しておく方法が好きですが、どちらにしても特に強い議論ではありません。また、Sinatraを使用する場合はミドルウェアを使用してこれを行うため、Railsおよび/またはSinatra(Railsに埋め込まれたNestaを実行することが多い)から構築されたアプリで使用できる手法を使用することを好みます。

とにかく、ここにあります:

1つ目はよりシンプル(そして私が使用しているもの)で、2つ目はさらにいくつかの機能を提供します(まだ必要ではありませんが、感謝しています)。

2
Graham Ashton