我的应用程序托管在Heroku上,并拥有www.mysite.com的证书
我正在努力解决
这是我到目前为止所拥有的:
class ApplicationController < ActionController::Base
before_filter :check_uri
def check_uri
redirect_to request.protocol + "www." + request.host_with_port + request.request_uri if !/^www/.match(request.host) if Rails.env == 'production'
end
但这似乎没有起作用。任何建议或可能不同的方法来解决确保HTTP和www。在URL?
由于
答案 0 :(得分:12)
对于SSL,请使用rack-ssl。
# config/environments/production.rb
MyApp::Application.configure do
require 'rack/ssl'
config.middleware.use Rack::SSL
# the rest of the production config....
end
对于WWW,请创建自己的Rack middleware。
# lib/rack/www.rb
class Rack::Www
def initialize(app)
@app = app
end
def call(env)
if env['SERVER_NAME'] =~ /^www\./
@app.call(env)
else
[ 307, { 'Location' => 'https://www.my-domain-name.com/' }, '' ]
end
end
end
# config/environments/production.rb
MyApp::Application.configure do
config.middleware.use Rack::Www
# the rest of the production config....
end
要在浏览器中对此进行测试,您可以编辑本地开发计算机上的/etc/hosts
文件
# /etc/hosts
# ...
127.0.0.1 my-domain-name.com
127.0.0.1 www.my-domain-name.com
在本地开发计算机上以生产模式运行应用程序
$ RAILS_ENV=production rails s -p 80
并浏览到http://my-domain-name.com/
,看看会发生什么。
在测试期间,您可能想要注释掉重定向到HTTPS站点的行。
可能还有一些方法可以使用许多Rails项目使用的标准单元测试和集成测试工具对其进行测试,例如Test::Unit
和RSpec
。
答案 1 :(得分:3)
Pivotal Labs有一些名为Refraction的中间件,它是mod_rewrite的替代品,除了它存在于源代码而不是Apache配置中。
对于你需要的东西可能有点过分,但它很容易处理这些东西。
答案 2 :(得分:1)
在Rails 3中
#config/routes.rb
Example::Application.routes.draw do
redirect_proc = Proc.new { redirect { |params, request|
URI.parse(request.url).tap { |x| x.host = "www.example.net"; x.scheme = "https" }.to_s
} }
constraints(:host => "example.net") do
match "(*x)" => redirect_proc.call
end
constraints(:scheme => "http") do
match "(*x)" => redirect_proc.call
end
# ....
# .. more routes ..
# ....
end
答案 3 :(得分:0)
我认为问题是你在Heroku上运行。查看关于Wildcard domains的Heroku文档:
“如果您希望自己的应用响应自定义域名下的任何子域名(如* .yourdomain.com),则需要使用通配符域加载项。...”
$ heroku addons:add wildcard_domains
另请参阅Redirecting Traffic to Specific Domain:
“如果您有多个域,或者您的应用有用户通过其Heroku子域访问它,但您之后切换到自己的自定义域,则可能希望让所有用户都使用之前的重定向进入同一域过滤器。像这样的东西可以完成这项工作:“
class ApplicationController
before_filter :ensure_domain
TheDomain = 'myapp.mydomain.com'
def ensure_domain
if request.env['HTTP_HOST'] != TheDomain
redirect_to TheDomain
end
end
end
答案 4 :(得分:0)
试试这个
def check_uri
if Rails.env == 'production' && request && (request.subdomains.first != "www" || request.protocol != 'https://')
redirect_to "https://www.mysite.com" + request.path, :status => 301 and return
end
end
答案 5 :(得分:0)
您最好的选择是设置与DNS提供商的重定向,以便在任何请求到达您的服务器之前很久就会发生。来自Heroku Dev Center:
子域重定向导致301永久重定向到指定子域的所有对裸域的请求,以便正确路由所有当前和未来请求,并在用户的位置字段中显示完整的www主机名。
DNSimple提供了一个方便的URL重定向,此处可以从中重定向
heroku-sslendpoint.com
裸域到www.heroku-sslendpoint.com
子域名。![]()
为了在Heroku上正确配置,www子域应该是a CNAME记录对yourappname.herokuapp.com的引用。
这不仅仅是DNSimple。我的DNS提供商是123 Reg,他们支持它,但称之为web forwarding
。