如何将两个域名(含www与非www)全量转发至单个Heroku应用?
Got it, let's break down how to fix this multi-domain redirect problem on Heroku step by step. Since you can't rely on .htaccess and have that single SSL certificate limitation, we'll need a mix of DNS configuration, Heroku app settings, and either app-level middleware or domain provider forwarding to cover all your redirect scenarios.
1. First, lock down your primary domain (domain1.com) on Heroku
This is where we'll attach the SSL certificate, so let's get this right first:
- Head to Register.com's DNS settings for
domain1.comandwww.domain1.com. Point both to your Heroku app's default domain (e.g.,yourapp.herokuapp.com) using CNAME records (forwww.domain1.com) or an ALIAS/ANAME record (for the apexdomain1.com, if Register.com supports it—Heroku recommends these for apex domains instead of A records since Heroku's IPs change). - Add both domains to your Heroku app via CLI or the dashboard:
heroku domains:add domain1.com heroku domains:add www.domain1.com - Install an SSL certificate that covers both
domain1.comandwww.domain1.com. You can use a free Let's Encrypt certificate (via tools likecertbotwith Heroku integration) or Heroku's Auto SSL if your app meets the eligibility criteria. Once installed,https://www.domain1.comandhttps://domain1.comshould load your app without SSL errors.
2. Handle the secondary domain (domain2.com)
The issue with GoDaddy's HTTPS forwarding failing is because Heroku's SSL certificate doesn't cover domain2.com—browsers throw a security warning before the redirect even has a chance to run. We have two solid options here:
Option A: Use your domain provider's HTTPS forwarding (with SSL for domain2)
If you want to keep domain2.com managed through GoDaddy's forwarding:
- In GoDaddy's DNS settings, configure permanent (301) URL forwarding for both
domain2.comandwww.domain2.comtohttps://www.domain1.com. Make sure you select "Forward only" (not "Forward with masking") so the address bar updates to your primary domain. - Critical step: Enable SSL for
domain2.comon GoDaddy. Most providers offer free basic SSL for forwarded domains now—turn this on so when users hithttps://domain2.com, GoDaddy's servers handle the SSL handshake first, then redirect without triggering browser warnings.
Option B: App-level middleware (most reliable, no provider dependencies)
If you want full control over all redirects from within your app, skip domain provider forwarding and use middleware to force every request to https://www.domain1.com. This works for all domains as long as you either:
- Use a SAN SSL certificate (covers multiple domains) that includes
domain2.comandwww.domain2.com, then bind those domains to your Heroku app, or - Accept that users hitting
https://domain2.comwill see a temporary SSL warning before redirecting (not ideal, but an option if you can't get a SAN cert).
Here are examples for common frameworks:
Node.js/Express
Add this middleware early in your app setup:
app.use((req, res, next) => { const targetDomain = 'www.domain1.com'; // Heroku passes the original protocol via X-Forwarded-Proto const currentProtocol = req.headers['x-forwarded-proto'] || req.protocol; if (req.hostname !== targetDomain || currentProtocol !== 'https') { return res.redirect(301, `https://${targetDomain}${req.originalUrl}`); } next(); });
Python/Django
Create a custom middleware class and add it to your settings.py:
from django.http import HttpResponsePermanentRedirect class ForcePrimaryDomainMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): target_domain = 'www.domain1.com' current_protocol = request.META.get('HTTP_X_FORWARDED_PROTO', 'http') if request.get_host() != target_domain or current_protocol != 'https': redirect_url = f'https://{target_domain}{request.get_full_path()}' return HttpResponsePermanentRedirect(redirect_url) return self.get_response(request)
Add 'yourapp.middleware.ForcePrimaryDomainMiddleware' to the top of your MIDDLEWARE list in settings.py.
Ruby/Rails
Add the rack-rewrite gem to your Gemfile, then configure it in config/application.rb:
Rails.application.config.middleware.insert_before 0, Rack::Rewrite do r301 %r{.*}, 'https://www.domain1.com$&', if: Proc.new { |env| env['HTTP_HOST'] != 'www.domain1.com' || env['HTTP_X_FORWARDED_PROTO'] != 'https' } end
3. Test all scenarios
Once everything is set up, verify every redirect works as expected:
http://domain1.com→ 301 tohttps://www.domain1.comhttp://www.domain1.com→ 301 tohttps://www.domain1.comhttp://domain2.com→ 301 tohttps://www.domain1.comhttp://www.domain2.com→ 301 tohttps://www.domain1.comhttps://domain1.com→ 301 tohttps://www.domain1.comhttps://domain2.com→ 301 tohttps://www.domain1.comhttps://www.domain1.com→ loads your app directly
Pro Tip: Use a SAN Certificate for Perfect HTTPS Coverage
If you can get a SAN (Subject Alternative Name) SSL certificate (Let's Encrypt offers free ones), include all four domains (domain1.com, www.domain1.com, domain2.com, www.domain2.com) in it. Upload this to Heroku, bind all four domains to your app, and use the app-level middleware. This eliminates all SSL warnings and keeps all redirect logic in one place—this is the cleanest solution long-term.
内容的提问来源于stack exchange,提问作者bentedder

