Nginx配置:动态多域名下将www重定向至非www域名
Got it, let's solve this dynamic redirect problem for your multi-domain SPA. Since you're using a default vhost with no hardcoded server_name and domains are constantly being added, we need a solution that automatically handles any www. prefix without updating config every time.
Core Approach
We'll use Nginx's regex matching and built-in variables to capture the www. prefix, then redirect to the corresponding non-www domain—no static domain lists required. This works seamlessly as you add new customer domains.
Step 1: Configure the www Redirect Server Block
Add a dedicated server block to catch all www.-prefixed domains first. Nginx will prioritize this block for any domain starting with www.:
server { listen 80; listen [::]:80; # Regex matches any domain starting with www., captures the rest in $1 server_name ~^www\.(.*)$; # Permanent redirect to non-www, preserving protocol and full request path return 301 $scheme://$1$request_uri; }
Step 2: Keep Your Default Vhost for Non-www Requests
Leave your existing default server block (the one without server_name) intact to handle all non-www traffic for your SPA. This block will catch every request that doesn't match the www. redirect block:
server { listen 80 default_server; listen [::]:80 default_server; # No server_name here—acts as the default for all unmatched requests # Your SPA core configuration (adjust paths to match your setup) root /var/www/your-spa-directory; index index.html; location / { try_files $uri $uri/ /index.html; # Critical for SPA client-side routing } }
Handling HTTPS (If Required)
If you're using HTTPS, replicate this setup for port 443. You'll need either a wildcard certificate (for subdomains of a single root domain) or a SAN (multi-domain) certificate that covers all your customer domains (both www. and non-www variants):
# Redirect www HTTPS to non-www HTTPS server { listen 443 ssl; listen [::]:443 ssl; server_name ~^www\.(.*)$; ssl_certificate /path/to/your/fullchain.pem; ssl_certificate_key /path/to/your/privkey.pem; return 301 $scheme://$1$request_uri; } # Default HTTPS server for non-www traffic server { listen 443 ssl default_server; listen [::]:443 ssl default_server; ssl_certificate /path/to/your/fullchain.pem; ssl_certificate_key /path/to/your/privkey.pem; root /var/www/your-spa-directory; index index.html; location / { try_files $uri $uri/ /index.html; } }
Quick Validation Steps
- Test your Nginx config for syntax errors with
nginx -tbefore reloading. - Apply changes with
sudo systemctl reload nginx(orsudo service nginx reloaddepending on your OS). - Use a temporary
302redirect instead of301during testing to avoid browser caching issues. Switch back to301once you confirm everything works (301 is SEO-friendly for permanent redirects).
内容的提问来源于stack exchange,提问作者Hadi Farnoud

