如果需要部署Nginx,我一直都会选择Linuxeye的OneInStack一键包进行部署,其中自带的typecho/wordpress等程序的rewrite规则也颇为好用,但是最近发现如果在添加网站时同时勾选了将www域名指向顶级域名的话,会在跳转时发生问题,也算是一个坑,在这里写出来希望能帮助大家。

首先还是如上文所说,这个问题只存在于Nginx下,如果你是Apache,那么得益于灵活的.htaccess设置,一般都不会存在此类问题(最近我也为了使用ImageVue,将Vultr也就是目前主要网站所在的VPS上的环境切换成了Apache,不由得感叹.htaccess实在太方便了)。
其实这个问题的发生,主要原因就是rewrite的前后优先级错乱。我们如果观察OneInStack LNMP的.conf文件,我们就会发现它的程序rewrite发生在www域名与顶级域名跳转之前:

include /usr/local/nginx/conf/rewrite/typecho.conf;    //typecho的rewrite规则
root /data/wwwroot/yorkchou.com;                       //网站目录
if ($host != yorkchou.com) {                           //www域名跳转至顶级域名
rewrite ^/(.*)$ $scheme://yorkchou.com/$1 permanent;

如上所示,这样一来首先生效的是/usr/local/nginx/conf/rewrite/typecho.conf这个typecho的rewrite规则。而如果熟悉typecho的就会知道,typecho默认链接形式是:http://xx.xx/index.php/xxx,而rewrite的目的就是去除“index.php",所以typecho.conf的内容是:

  if (-f $request_filename/index.html){ 
    rewrite (.*) $1/index.html break;
    }
  if (-f $request_filename/index.php){
    rewrite (.*) $1/index.php;
    }
  if (!-e $request_filename){
    rewrite (.*) /index.php;
    }

如果这样的规则生效在www域名跳转到顶级域名之前,那么自然就会发生跳转错误,所以解决方法也很简单——调节优先级。

  include /usr/local/nginx/conf/rewrite/none.conf;       //将rewrite规则设为none或者直接删除这一行
  root /data/wwwroot/yorkchou.com;                       //网站目录
  if ($host != yorkchou.com) {                           //首先生效www域名跳转至顶级域名
    rewrite ^/(.*)$ $scheme://yorkchou.com/$1 permanent;
    }
  if ($ssl_protocol = "") { return 301 https://$host$request_uri;  //如果你用了https,可以强制跳转https

  if (-f $request_filename/index.html){                  //将typecho的rewrite规则手动移动到conf中
    rewrite (.*) $1/index.html break;
    }
  if (-f $request_filename/index.php){                  //将typecho的rewrite规则手动移动到conf中
    rewrite (.*) $1/index.php;
    }
  if (!-e $request_filename){                           //将typecho的rewrite规则手动移动到conf中
    rewrite (.*) /index.php;
    }

这样一来,问题就迎刃而解了!

Last modification:July 10, 2019
If you think my article is useful to you, please feel free to appreciate