loading...

Utilize Nginx to fulfill 301 redirect to root domain of https

chanvin profile image Chanvin Xiao Originally published at chanvinxiao.com ・3 min read

Base on consideration of SEO and security, the redirection should be 301, which will be handled generally via Nginx

Result to Accomplish

The following address need to be redirected to the root domain of https https://chanvinxiao.com

Different between 301 and 302

301 is to redirect permanently, 302 is to redirect temporary, and the major distinction is lay in the handling way of search engine

  • 301:search engine will transfer weight and PR value
  • 302:search engine will not handle additionally

Now I want search engine treat the original url as non-existence anymore, and completely shift to the new address, so 301 will be used

Redirect Http to Https

The simplest way is to return a redirected address, and add a 301 status code in the middle (or else default 302 will be supposed)

server {
  listen 80;
  return 301 https://$host$request_uri;
}
  • return and rewrite are both rewrite directive of Nginx, since here the path don't need to be changed, return will be more convenient
  • $host and $request_uri are both Nginx http module's embedded variables, the combination of these two parameters is equivalent to getting rid of http:// for request url

Www Redirect to Root Domain

Only need to handle in https, because all http has been redirected to https

server {
  listen 443 ssl;
  server_name ~^(?<www>www\.)?(.+)$;
  if ( $www ) {
    return 301 https://$2$request_uri;
  }
...
  • Regular Expression matching of server_name have been utilized, which can been enabled via adding ~ in front of its value, and PCRE grammar is supported
  • Regex usage is to determine if there's prefix www, and to capture root domain, which will generate two variable, one is name capture variable $www, the other is numeric capture variable $2
  • numeric capture variable is not supported in if, or else there will be error thrown (unknown "1" variable), that's why ?<www> is added to assign $1 to $www

Reduce Redirect Times

The result is fulfilled by the above settings, but there's a flaw: http://www.chanvinxiao.com will redirect to https://www.chanvinxiao.com firstly, then redirect again to https://chanvinxiao.com. redirecting twice is definitely not as good as redirecting once, so one-stop would be better, and the http config will be modified as follow:

server {
  listen 80;
  server_name ~^(?:www\.)?(.+)$;
  return 301 https://$1$request_uri;
}
  • In the corresponding server of http, server_name also is changed to regex mode, and $host is substituted with captured root domain $1
  • Www will be removed directly, so it's not necessary to capture, use ?: symbol to fulfill grouping without capturing, so the following root domain becomes $1
  • Thus the result is that no matter there is www or not, it will be redirected to https domain without www

Summary

There is not need to appoint specific domain in the above config, so it will be convenient to be compatible and migrate, and the following feature of Nginx is used:

  • Regular expression matching of server_name
  • return directive which receive status code and address
  • $host and $request_uri embedded variables

Posted on May 23 by:

chanvin profile

Chanvin Xiao

@chanvin

Web / Frontend / Architecture

Discussion

markdown guide