Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
267 views
in Technique[技术] by (71.8m points)

Nginx rewrite non-www-prefixed domain to www-prefixed domain

I see the Nginx HttpRewriteModule documentation has an example to rewrite a www-prefixed domain to a non-www-prefixed domain:

if ($host ~* www.(.*)) {
  set $host_without_www $1;
  rewrite ^(.*)$ http://$host_without_www$1 permanent; # $1 contains '/foo', not 'www.mydomain.com/foo'
}

How can I do the reverse-- rewrite a non-www-prefixed domain to a www-prefixed domain? I thought maybe I could do something like the following but Nginx doesn't like the nested if statement.

if ($host !~* ^www.) {                       # check if host doesn't start with www.
    if ($host ~* ([a-z0-9]+.[a-z0-9]+)) {    # check host is of the form xxx.xxx (i.e. no subdomain)
        set $host_with_www www.$1;
        rewrite ^(.*)$ http://$host_with_www$1 permanent;
    }
}

Also I wanted this to work for any domain name without explicitly telling Nginx to rewrite domain1.com -> www.domain1.com, domain2.com -> www.domain2.com, etc. since I have a large number of domains to rewrite.

question from:https://stackoverflow.com/questions/1629231/nginx-rewrite-non-www-prefixed-domain-to-www-prefixed-domain

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As noted in the Nginx documentation, you should avoid using the if directive in Nginx where possible, because as soon as you have an if in your configuration your server needs to evaluate every single request to decide whether to match that if or not.

A better solution would be multiple server directives.

server {
        listen 80;
        server_name website.com;
        return 301 $scheme://www.website.com$request_uri;
}

server {
        listen 80;
        server_name www.website.com;
        ... 
}

If you're trying to serve an SSL (HTTPS) enabled site, you got more or less three different options.

  1. Set up multiple IP addresses having each server directive listening on their own IP (or different ports if that's an option for you). This options needs SSL certificates for both website.com and www.website.com, so either you have a wild card certificate, a UNI certificate (multiple domains) or just plainly two different certificates.
  2. Do the rewrite in the application.
  3. Use the dreaded if directive.

There is also an option to use SNI, but I'm not sure this is fully supported as of now.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...