因此,目前,由于与我的主机提供商(Heroku)的限制,我正在手动地从一个裸域定向。一切都很好。问题是,如果用户访问mydomain.com/ that,则将在没有/route的情况下向/route发出重定向。我将如何重新布置路线,但仍然重定向到www。?
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :ensure_domain
APP_DOMAIN = 'www.domain.com'
def index
end
def ensure_domain
if Rails.env.production?
if request.env['HTTP_HOST'] != APP_DOMAIN
redirect_to "http://#{APP_DOMAIN}", :status => 301
end
end
end
end编辑
我从我的ApplicationController中删除了上面的代码,并选择了使用hurikhan77建议的折射宝石,这解决了我的问题。
这是我用过的refraction_rules.rb。
Refraction.configure do |req|
if req.host == "domain.com"
req.permanent! :host => "www.domain.com"
end
end发布于 2012-11-24 00:42:01
我建议对此使用折射宝石:http://rubygems.org/gems/refraction
发布于 2012-11-24 13:10:39
理想情况下,您应该在您的web服务器配置中设置类似的规则。请求将变得更快,因为它们甚至无法到达rails堆栈。也不需要向应用程序添加任何代码。
但是,如果您在某些受限的环境中运行,比如heroku,我建议您添加一个机架中间件。(只是为了指导原则,不能保证这个特定的代码是没有bug的)
class Redirector
SUBDOMAIN = 'www'
def initialize(app)
@app = app
end
def call(env)
@env = env
if redirect?
redirect
else
@app.call(env)
end
end
private
def redirect?
# do some regex to figure out if you want to redirect
end
def redirect
headers = {
"location" => redirect_url
}
[302, headers, ["You are being redirected..."]] # 302 for temp, 301 for permanent
end
def redirect_url
scheme = @env["rack.url_scheme"]
if @env['SERVER_PORT'] == '80'
port = ''
else
port = ":#{@env['SERVER_PORT']}"
end
path = @env["PATH_INFO"]
query_string = ""
if !@env["QUERY_STRING"].empty?
query_string = "?" + @env["QUERY_STRING"]
end
host = "://#{SUBDOMAIN}." + domain # this is where we add the subdomain
"#{scheme}#{host}#{path}#{query_string}"
end
def domain
# extract domain from request or get it from an environment variable etc.
end
end您也可以单独测试整个事件。
describe Redirector do
include Rack::Test::Methods
def default_app
lambda { |env|
headers = {'Content-Type' => "text/html"}
headers['Set-Cookie'] = "id=1; path=/\ntoken=abc; path=/; secure; HttpOnly"
[200, headers, ["default body"]]
}
end
def app()
@app ||= Rack::Lint.new(Redirector.new(default_app))
end
it "redirects unsupported subdomains" do
get "http://example.com/zomg?a=1"
last_response.status.should eq 301
last_response.header['location'].should eq "http://www.example.com/zomg?a=1"
end
# and so on
end然后,您只可以将其添加到生产(或任何首选环境)中。
# production.rb
# ...
config.middleware.insert_after 'ActionDispatch::Static', 'Redirector'如果您想在开发中测试它,请将同一行添加到development.rb中,并向主机文件(通常是/etc/host)添加一条记录,将yoursubdomain.localhost视为127.0.0.1
发布于 2012-11-23 23:37:07
不确定这是否是最好的解决方案,但您可以重新定位request.referrer并在.com之后提取任何内容,并将其附加到APP_DOMAIN中。
或者我想你可以在第一天之前把所有东西都拿出来。在request.env['HTTP_HOST']中,假设您不打算使用子域,则添加替换为http://www.。
https://stackoverflow.com/questions/13536724
复制相似问题