Nginx之rewrite配置

Rewtrite : 其主要目的是为了进行URL 重写,进行URL重定向。主要采用PCRE: Perl Compatible Regular Expressions(Perl兼容正则表达式语法)进行规则匹配,所以需要先安装PCRE lib。

 

一 rewrite规则

重写规则是rewirte的基础。在Nginx中,使用ngx_http_rewrite_module模块支持URL重写。该模块是标准的http模块。

 

二 if指令

用来支出条件判断,并且根据条件判断结果选择不同的Nginx配置,可以在server块或者location块中配置,语法结构:

if (condition) {…….}

对于condition而言:

# 变量名:如果变量的值为空字符串或者以0开头的任意字符串,if指令认为条件为false,其他情况认为条件为true,比如:

if($slow) {

    //nginx配置

}

 

# 比较字符串是否相等,字符串无需加引号

if ($request_method = POST) {

      return405;

}

# 使用正则表达式对变量进行匹配,匹配成功时,if条件指令为true,否则为false。

变量与正则表达式之间用"~""~*" "!~" "!~*" 连接,

"~":大小写敏感

"~*": 大小写不敏感

"!~":"~" 和"~*"匹配失败时,if指令认为条件为true,否则为false

if ($http_user_agent ~ MSIE) {

      #$http_user_agent 是否包含MSIE字符

}

 

# 文件和目录是否存在,文件是否可执行

文件是否存在:使用-f 和 !-f

目录是否存在:使用-d 和 !-d

文件是否可执行:使用-x和!-x

 

if (-f $reqeust_filename) {

      //......

}

 

三 break、return指令

3.1 break指令

该指令用于中断当前相同作用域中的其他Nginx配置。与该指令处于同一作用域的Nginx配置,位于他前面的指令配置生效,位于后面的指令配置无效。该指令可以在server块和location块以及if块中使用。

location / {

      if($slow) {

           set$id $1

           break;

           limit_rate10k

      }

}

3.2 return指令

该指令用于完成队请求的处理,直接向客户端返回响应状态码。处于该指令后的所有Nginx配置是无效的。该指令可以在server或者location或者if块中使用。

return [ text]

return code URL;

return URL;

code: 表示返回给客户端的状态码

text: b表示相应的具体响应体内容

URL: 没有状态码的URL视为一个302状态码

 

四 rewrite指令

该指令通过正则表达式的使用来改变URI,可以同时存在一个或者多个指令,按照顺讯一次对URL进行匹配和处理。我们也可以理解我对于多条rewrite指令,顺序靠前的且匹配的优先执行。

语法格式:

rewrite regex replacement [flag];

regex: 用于匹配URI的正则表达式,使用括号()标记要截取的内容

replacement: 匹配成功后用于替换URI中被截取内容的字符串。默认情况下如果该字符串是由http://或者https://开头的,则不会继续向下对URI进行其他处理

 

flag: 用来设置rewrite对URI的处理行为,选项有:

# last: 停止当前这个请求,并根据rewrite匹配的规则重新发起一个请求。新请求又从第一阶段开始执行。

# break:相对last,break并不会重新发起一个请求,只是跳过当前的rewrite阶段,并执行本请求后续的执行阶段。

# redirect: 重写后的URI返回给客户端,状态码为302,指明是临时重定向

# permanent:重定向的URI返回给客户端,状态码为空301,指明是永久重定向

rewrite a.example.com http://b.example.com$request_uri? permanent;

    location/break/ {

       rewrite ^/break/(.*) /test/$1 break;

        echo"break page";

    }

 

    location/last/ {

        rewrite ^/last/(.*) /test/$1 last;

         echo"last page";

    }   

 

    location/test/ {

       echo"test page";

}

结果如下:

[[email protected] conf]$ curlhttp://a.example.com/break/1111

break page

[[email protected] conf]$ curl http://a.example.com/test/2222

test page

[[email protected] conf]$ curlhttp://a.example.com/last/3333

test page

 

五 rewrite_log指令

rewrite_log on | off

该指令配置是否开启URL重写日志输出功能

 

 

六 set指令

用于设置一个新的变量,语法结构为:

set 变量名 变量值

 

七 rewrite常用全局变量

Nginx之rewrite配置

Nginx之rewrite配置

八 域名跳转

server {

      listen80;

      server_namejump.myweb.com;

      rewrite^/ http://www.myweb.info/;

}

server {

      listen80;

      server_namejump.myweb.name  jump.myweb.info;

      if($host ~ myweb\.info) {

           rewrite^(.*) http://jump.myweb.name/$1 permanent;

      }

}

 

九 域名镜像

镜像网站是指将一个完全相同的网站,分被放置到几个服务器上,并分别使用独立的URL,其中一个服务器上的网站叫做主站,其他的为镜像网站。镜像网站可以保存网页信息,历史性数据等,可以通过镜像网站提高在不同的地区响应速度,平衡网站的流量负载,解决网络带宽限制和*等

使用Nginx的rewrite实现镜像域名的跳转,原理就是将不同的镜像URL重写到相同的URL就可以了。

 

十 独立域名

当一个网站包含多个板块的时候,可以为其中某些板块设置独立的域名。

server {

      listen80;

      server_namebbs.exampel.com;

      rewrite^(.*) http://www.example.com/bbs$1 last;

      break;

}

 

server {

      listen81;

      server_namehome.exampel.com;

      rewrite^(.*) http://www.example.com/home$1 last;

      break;

}

 

十一 目录自动添加/

一般情况,对于网站默认的资源,我们不加具体的URL访问是可以的,比如访问www.example.com的时候,如果我们设置了站点的首页是index.html 那么直接访问www.example.com就可以成功访问。

但是如果请求的资源文件在二级目录下呢,这样的习惯无法正常访问资源,比如访问http://www.example.com/bbs/index.html时,如果URL省略为http://www.example.com/bbs,将末尾的斜杠也省了,访问就出问题,即Nginx服务器访问二级目录时不加斜杠无法访问。但是我们不可能要求客户端始终按照我们的要求在末尾加斜杠。如何解决呢?

server {

      listen80;

      server_namewww.example.com;

      location^~ /bbs {

           if(-d $request_filename) {

              # 表示任意域名非/结尾 重定向到该任意域名以斜杠结尾

                 rewrite^/(.*) ([^/])$ http://$host/$1$2/ permanent;

           }

      }

}

 

十二 目录合并

有时候我们的网站的资源目录是多层级的,比如:

http://www.example.com/11/22/45/1023.html

这种方式不利于搜索引擎搜索,那么我们会尝试想办法让URL的目录级数看上去少一些呢?

server {

      listen80;

      server_name www.example.com;

      location^~ /server {

           rewrite^/server/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)\.html$/server-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.html last;

           break;

      }

}

 

十三 防盗链

盗链是一种损害原有网站的合法利益,给原有网站所在的服务器造成额外的负担的非法行为。要采取防盗链的措施,首先理解盗链的实现原理:

比如我们自己网站的图片,是引用其他服务器的图片资源,那么客户端获取图片的请求,就是从其他服务器上下载的,这样对其他服务器不是很公平,增加了网络带宽。

要实现防盗链,HTTP头部的Referer头域和采用URL的格式访问当前网页或者文件的原地址。通过该头域可以检测到Referer头域中值并不是自己站点的URL,就采取阻止措施。

但是Referer头域的值是可以更该的,该方法不能够完全阻止所有的盗链行为。

valid_referers none | blocked | server_names|string......;

none: 检测Referer头域不存在

blocked: 检测Referer头域的值被防火墙或者代理服务器删除或者伪装的情况

server_names: 设置一个或者多个URL,查看Referer头域的值是这些的URL中的某个

 

server {

      listen80;

      server_namewww.example.com;

      location~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ {

           valid_referersnoen blocked server_names *.ecom.com

           if($valid_referers) {

                 rewrite^/ http://www.example.com/images/forbbiden.png

           }

      }

}