Как перенаправить без www, используя Rails 3/Rack?
Я понимаю, что есть много вопросов, которые отвечают на это. Я знаком с методами .htaccess
и nginx.conf
, но у меня нет доступа к таким традиционным методам настройки на героку.
Simone Carletti дал этот ответ, который использует Rails 2.x Metals, но Я использую Rails 3, и это несовместимо,
Перенаправить не-www запросы на URL-адреса в Rails
Обратите внимание:
Я не ищу простой before_filter
в своем приложении ApplicationController. Я бы хотел сделать переписку, подобную симоне. Я считаю, что это работа для веб-сервера или промежуточного программного обеспечения, такого как Rack, по крайней мере, поэтому я хотел бы оставить этот бит вне фактического кода приложения.
Цель
redirect to status
----------------------------------------------------
www.foo.com foo.com 301
www.foo.com/whatever foo.com/whatever 301
Только хосты, соответствующие /^www\./
, должны быть перенаправлены. Все остальные запросы следует игнорировать.
Ответы
Ответ 1
в Rails 4 удаление www. с любого URL-адреса, в то время как сохранение пути может быть достигнуто просто с помощью:
# config/routes.rb
constraints subdomain: 'www' do
get ':any', to: redirect(subdomain: nil, path: '/%{any}'), any: /.*/
end
Напротив, добавление www. к началу любого URL-адреса, который еще не имеет его, может быть достигнуто посредством:
# config/routes.rb
constraints subdomain: false do
get ':any', to: redirect(subdomain: 'www', path: '/%{any}'), any: /.*/
end
Ответ 2
Там будет лучший подход, если вы используете 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
Ответ 3
Мне очень нравится использовать Rails Router для таких вещей. Предыдущие ответы были хорошими, но я хотел что-то общее, что я могу использовать для любого URL-адреса, который начинается с "www".
Я думаю, что это хорошее решение:
constraints(:host => /^www\./) do
match "(*x)" => redirect { |params, request|
URI.parse(request.url).tap {|url| url.host.sub!('www.', '') }.to_s
}
end
Ответ 4
Взгляните на это промежуточное программное обеспечение, оно должно делать именно то, что вы хотите:
http://github.com/iSabanin/www_ditcher
Сообщите мне, если бы это сработало для вас.
Ответ 5
Однострочная версия решения Duke. Просто добавьте в начало route.rb
match '(*any)' => redirect { |p, req| req.url.sub('www.', '') }, :constraints => { :host => /^www\./ }
Ответ 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
Ответ 7
Если вы хотите перенаправить из домена верхнего уровня (TLD) в субдомен www, используйте этот код:
constraints :subdomain => '' do
match '(*any)' => redirect { |p, req| req.url.sub('//', '//www.') }
end
Примечание. Этот код использует sub, а не gsub, потому что sub заменяет первое вхождение двойных слэшей, где gsub заменяет все двойные слэши.
Ответ 8
Для Rails 4 вышеупомянутые решения должны прилагаться к конструкции Verb, например. 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
Ответ 9
Ничего плохого в подходах выше, но есть также несколько драгоценных камней, которые обеспечивают промежуточное ПО Rack для этого.
Мне нравится, как они сохраняют это поведение отдельно от самого приложения, но это не очень сильный аргумент. Я также использую промежуточное ПО для работы с Sinatra, поэтому предпочитаю использовать технику, которую я могу использовать для приложений, созданных из Rails и/или Sinatra (я часто запускаю Nesta, встроенную в Rails).
В любом случае, вот они:
Первое проще (и тот, который я использовал), в то время как второй предлагает еще пару функций (которые мне еще нужны, но оцените).