Nginx 之四: Nginx服务器的rewrite、全局变量、重定向和防盗链相关功能

一:Nginx 后端服务器组的配置:php

一、upstream:css

用于设置后端服务器组的主要指令,upstream相似于以前的server块或http块,用法以下:html

upstreame  Myserver{ 
   #ip_hash;
  #least_conn;
  #fair;
  
  #hash $request_uri;
  #hash_method crc32;
  server
192.168.0.2:8080 #weight 2 max_fails 3 fail_timeout 60;   192.168.0.3:8080 backup;   192.168.0.4:8080 down;     } #Myserver是后端服务器组的名称,在大括号里面填写后端服务器的IP和端口信息,默认状况下服务器组被调用之后会使用轮询调度的方式调用组内的后端服务器。
#keepalived_timeout; #保持的空闲会话的时常,在此时间内客户端不进行操做,服务器将断开与客户端的链接。此数值不能太大,Nginx从1.1.4开始支持。 #ip_hash; 实现会话保持功能,即将某个客户端的请求定向到组内的同一台服务器,保证客户端与服务器之间创建稳定的会话,只有服务器处于无效状态时,会话才会被转发给组内其余的服务器。 #server 用于定义一台后端服务器。 #
192.168.0.2:8080 是后端服务器的IP,端口是8080。 #weight = number; #配置权重,与ip_hash有冲突,由于ip_hash是将请求固定在同一个后端服务器的,而weight是根据权重轮训的,所以不能同时配置在一个upstream内。 #max_fails = number #设置一个失败的请求次数,在必定时间内超过这个次数就认为服务器是无效的,如能够设置为3。 #在失败3次之后的60秒将再也不将请求分发给失效的server也不在检查此server的状态,默认时间是10秒。 #backup; #将一台服务器标记为备份服务器,只有当全部正常服务器所有不可用的时候才会使用备份的服务器。 #down #将一台服务器标记为永久不可用的状态,一般与ip_hash配合使用。

 二、nginx 的 upstream支持的集中调度算法:nginx

一、轮询(默认) 
   每一个请求按时间顺序逐一分配到不一样的后端服务器,若是后端服务器down掉,能自动删除。 
二、weight 
   指定轮询概率,weight和访问比率成正比,用于后端服务器性能不均的状况。 
三、ip_hash 
   每一个请求按访问ip的hash结果分配,这样每一个访客固定访问一个后端服务器,能够解决session 保持的问题。  
四、fair(第三方) 
   能够依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配,Nginx自己默认是不支持fair的,若是须要使用这种调度算法,必须下载Nginx的upstream_fair模块。
五、url_hash(第三方)
  按访问url的hash结果来分配请求,使每一个url定向到同一个后端服务器,能够进一步提升后端缓存服务器的效率,Nginx自己默认是不支持url_hash的,若是须要这种高度算法,必须安装Nginx的hash软件包。
六、least_conn
  根据后端服务器的链接情况进行分配客户请求,链接最少的服务器将被有限分配客户端请求。

二:Nginx服务器的rewrite功能介绍:web

 Nginx服务器利用ngx_http_rewrite_module 模块解析和处理rewrite请求,因此说此功能依靠 PCRE(perl compatible regularexpression),所以编译以前要安装PCRE库,rewrite功能时nginx服务器的基本功能之一,用于实现URL的重写,URL的重写是很是有用的功能,好比它能够在咱们改变网站结构以后,不须要客户端修改原来的书签,也无需其余网站修改咱们的连接,就能够设置为访问,另外还能够在必定程度上提升网站的安全性。正则表达式

一、地址重写与地址转发:算法

地址重写和地址转发是两个不一样的概念,地址重写是其实是为了实现址标准化,就像访问www.baidu.cn能够出现www.baidu.com的首页,服务器会把www.baidu.cn重写成www.baidu.com,浏览器的地址栏也会显示www.baidu.com,而转发指的是将一个域名指向另外一个已有站点的过程,地址栏的地址保持不变,所以地址转发和地址重写的大体区别以下:chrome

地址转发后客户端浏览器地址栏中的地址显示是不变的,而地址重写后地址栏中的地址会变成正确的地址。
在一次地址转发过程当中只会产生一次网络请求,而一次地址重写产生两次请求。
地址转发通常发生在同一站点项目内,而地址重写则没有限制。
地址转发到的页面能够不用全路径名表示,而地址重写到的页面必须使用彻底的路径名表示。
地址转发过程当中,能够将客户端请求的request范围内的属性传递给新的页面,但地址重写不能够。
地址转发的速度比地址重写的速度快。

  二、if指令:express

2.1:用于条件判断,并根据条件判断结果选择不一样的Nginx配置,能够配置在server或location块中进行配置,用法以下:apache

if ($变量) { 
  action
}

注: 若是$变量的值为空字符串或是以0开头的任意字符串,则if指令认为该条件为false,其余条件为true。

2.2:使用“=”(等于)和“!=”(不等于)比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false。

if ($request_method = POST) {
      return 405;  
} #条件里的字符串不须要加引号

2.3:使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,不然认为false,变量与表达式之间使用如下符号连接:

双目测试:运算所需变量为两个的运算符叫作双目运算符,以下几个运算符:

~: #表示在匹配过程当中区分大小写字符,(能够经过正则表达式匹配),知足匹配条件为真,不知足为假。
~*: #表示在匹配过程当中不区分大小写字符,(能够经过正则表达式匹配),知足匹配条件为真,不知足问假。
!~:#区分大小写不匹配,不知足为真,知足为假,不知足为真。
!~*:#为不区分大小写不匹配,知足为假,不知足为真。

^~ :#若是把这个前缀用于一个常规字符串,那么告诉nginx 若是路径匹配那么不测试正则表达式。

注意:使用~和~!在匹配成功时if指令认为条件为true,匹配失败为false,使用!~和!~*匹配失败时if指令认为条件为true,不然为false,在正则表达式中,可使用小括号对变量进行截取,在大括号中使用$!...$9引用截取的值,以下:

if ($http_user_agent ~ MSIE) {  #if语句尽可能用在location当中,尽可能不要在http或server中使用,会出现莫名的错误。
     #判断客户端的浏览器中是否含有MSIE的字符串,若是包含则为true  
}

#########################################
if ($http_cookie ~* "id="([^;]+)(?:;)") {
    #Nginx配置,可使用$!和$2获取截取到的值,如:
     # set $id $1; 将截取到的id的值赋值给$id变量以备后用  
}
注意:整个正则表达式通常不须要加引号,可是若是含有右大括号"}"或者分分号";"的时候,就必需要给整个正则表达式加上引号""

三、文件和目录测试:单目测试,判断文件或者目录是否存在

3.1 -f和! -f:判断请求的文件是否存在和是否不存在

-f 表示若是请求的文件存在,则if指令为true,若是请求的文件不存在,则if指令为false。使用! -f的时候,若是请求的文件不存在可是目录存在,if指令认为条件为true,若是请求的文件和目录都不存在,则if指令认为条件为false,若是请求的文件存在,也为false,以下:
if (-f $request_filename) {
    #判断请求的文件是否存在
}

if (! -f $request_filename) {
   #判断请求的文件是否不存在
}

3.2 -d和! -d: #判断请求的目录是否存在和是否不存在。

使用-d时,若是请求的目录存在,则if指令认为条件为true,若是请求的目录不存在,则认为条件为false,当使用! -d的时候,若是请求的目录不存在可是目录的上级存在,if指令认为条件为true,若是该目录和他的上级都不存在,则为false,若是请求的目录存在也未false,和of和! -f基本一致。

3.3 -e和! -e: #判断请求的文件或目录是否存在和是否不存在。

判断文件或目录是否存在,至关于-f和-d的功能合体,当使用-e时,若是请求的文件或目录存在则if指令认为条件为true,不然为false,当使用! -e时,若是请求的文件或目录以及该文件的上级都不存在,则为false,不然为true。

3.4 -x和 ! -x: #判断文件是否可执行和是否不可执行。

使用-x若是文件可执行则返回true,不然为fasle,使用! -x的时候若是文件不可执行返回true,不然为false。

四、break指令:用于中断当前相同做用域中的其余Nginx配置,与该指令处于同一做用域的Nginx配置中,位于它前面的配置生效,位于后面的指令配置就再也不生效了,Nginx服务器在根据配置处理请求的过程当中遇到该指令的时候,回到上一层做用域继续向下读取配置,该指令能够在server块和location块以及if块中使用,使用语法以下:

location /test {
        root   html;
        index  index.html index.htm;  
     break;  #return以后的将再也不执行,以前的能够执行
      }

 五、return指令:用于完成对请求的处理,并直接向客户端返回响应状态码,处于此指令后的全部配置都将不被执行,return能够在server、if和location块进行配置,用法以下:

return (text); #返回给客户端的响应体内容,能够调用变量
return code; #返回给客户端HTTP状态码,范围为0-999
return URL; #返回给客户端的URL地址

注意:从nginx 0.8.42开始,当code使用301时表示永久重定向,302为临时重定向。303表示当前的响应能够在另外一个URL找到,307表示请求的资源临时从不一样的URL响应

六、rewrite指令:经过正则表达式的匹配来改变URI,能够同时存在一个或多个指令,按照顺序依次对URI进行匹配。

URI(universal resource identifier):通用资源标识符,用于对网络中各类资源进行标示,有存放资源的主机名、片断标识符和相对URL三部分组成,存放资源的主机名一把由传输协议(scheme)、主机和资源路径三部分组成,片断标识符执行资源内容的具体元素,相对URL标示主机上的相对路径,通常格式为:scheme:[//] [[用户名[:密码]@]主机名:[端口号]][/资源路径名],如http://www.a.com:8080/path/file/index.html,Nginx就是对其中的URI /path/file这部分进行处理和匹配,可是不能处理http://www.a.com,由于Nginx接受到的URL不包含http://www.a.com。
URL(uniform resource location):统一资源定位符,是用于在Internet中描述资源的字符串,是URL的子集,主要包括传世协议(scheme)、主机(IP、端口号或者域名)和资源具体地址(目录和文件名)等三部分,通常格式为 scheme://主机名[:端口号][/资源路径],如:http://www.a.com:8080/path/file/index.html就是一个URL路径
URI就是一种资源定位机制,它是比较笼统地定位了资源,并不局限于客户端和服务器,而URL就定位了网上的一切资源,只要是网上的资源,都有惟一的URL。

 

注:rewrite指令接收到的URI为 /path/file,不包含参数,如/path/file/arg1=value1&argv2=value2,只会接收到/path/file,不包含arg1=value1&argv2=value2,可是咱们可使用nginx内置的全局变量$request_uri来匹配用户的uri,在$request_uri后面要添加问号,replacement支持nginx全局变量的使用,经常使用的还要$uri和$args等,如:

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

注意:replacement是匹配成功后用于替换URL中被截取内容的字符串,默认状况下,若是该字符串是有http://或者https://开头的,则不会继续向下进行其余处理,并且直接将重写后的URL返回给客户端。

七、flag:用来设置rewrite对URI处理的行为或动做,能够为一下四个当中的一个:

7.一、last:终止继续在本location块中处理接受到的URL,并将在本location中从新的URL做为一个新的URL,继续使用后面的各location块进行处理,该标志将重写后的URL从新再server块中执行,为重写后的URI转入到其余location块并继续处理的机制,nginx服务器的last处理超过10次循环以后将返回错误代码500,使用方法以下:

location / {
    rewrite ^(/test/.*)/msie(.*)\..*$  $1/test/mp3/$2.html break;
    rewrite ^(/test/.*)/other(.*)\.*$ $1/test/other/$2.html break;    
}

注:若是URI在第二行被匹配成功并处理,Nginx服务器不会继续使用第三行的配置和匹配处理新的URL,而是让全部的location快从新匹配和处理新的URI,即一旦在本location中匹配成功一行,就跳出本location并在下一个location匹配,直到在下一个location匹配成功后再跳出下一个location继续下下一个,直到最后一个为止。

7.三、break:将你的URI做为一个新的URI,在本快中继续进行处理,该标志将重写后的地址在当前的location快中执行,不会将新的URI转向其余的location模块,以下:

注意:若是第二行被匹配并处理成功,Nginx服务器将新的URI继续在本location块中使用第三行匹配和处理,新的URI始终在一个location以内匹配和处理,直到本location最后一个匹配条件。last通常写在server和if中,而break通常使用在location中
一、last通常写在server和if中,而break通常使用在location中
二、last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
三、break和last都会继续执行后面的rewrite指令,只是last会终止本location的匹配跳转到其余location,而break只会在当前location继续匹配,直到最后一条匹配结果为止,不会跳转到其余location。

7.四、redirect:将重写后的URI返回给客户端,状态码为302,指明是临时重定向URI,主要用在replacement变量不是以http或https开头的状况下。

7.五、permanent:将重写后的URI返回给客户端,代码为301,注明是永久重定向。

注意:在使用flag的时候,

八、rewrite_log:用于配置是否开启URL重写日志的输出功能,用法以下:

rewrite_log on|off; #默认为off。,若是设置为开启,URL的相关日志将以notice级别的输出到error_log配置的文件当中。

九、set:用于设置一个新的变量,其用法结构为:

set  variable value;  #variable为变量的名称,要使用$做为变量的第一个字符,且变量名不能与nginx服务器预设的全局变量相同
value:为变量的值,能够是字符串、其余变量和变量组合等。

十、uninitialized_variable_warn:用于配置使用未初始化的变量时,是否记录告警日志,用法以下:

uninitialized_variable_warn on|off;

 四、root和alias:

root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location,如:

location /bbs {
        root   html;  #必需要在html目录中建立一个bbs目录才能够访问,不然报错。
        index  index.html;
        }

alias:定义路径别名,会把访问的路径从新定义到其指定的路径,如:

 location /newweb { #当访问newweb的时候,会显示alias定义的 /usr/local/nginx/html/newweb/里面的内容。
        alias  /usr/local/nginx/html/newweb/;
        }

注:alias后面必需要用“/”结束,不然会找不到文件,而root要结合location,要么都有/,要么都没有/,若是一个有一个没有在访问的时候会出错。

3、Rewrite经常使用的全局变量:

1.Nginx服务器内置了不少预先定义好的内置变量,就要方便获取不少相关的服务器信息以及与请求相关的指令、参数当信息,能够更加方便的用户进行自定义的功能定义等,具体变量以下以下:

1.一、$args:变量中存放了URL中的指令,好比http://mobile.weathercn.com/index.do?id=101290101&partner=中的id=101290101&partner=,并且能够有多个指令。

1.二、$content_length:保存了请求报文头部中的content-lenght字段。

1.三、$content_type:保存了请求头部中的content-type字段。

1.四、$document_root:保存了针对当前资源的请求的系统根目录。如:

1.五、$document_uri:保存了当前请求中不包含指令的URI,主注意是不包含请求的指令,好比http://hfnginx.chinacloudapp.cn/index.do?id=101060101&partner=会被定义为/index.do。

1.六、$host:存放了请求的服务器名称。

1.七、$http_user_agent:客户端浏览器的详细信息,如使用chrome和Firefox访问则显示以下:

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 #chrome的浏览器信息
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0 #Firefox的浏览器信息

1.八、$http_cookie:客户端的cookie信息。

1.九、$limit_rate:若是nginx服务器使用limit_rate配置了显示网络速率,则会显示,若是没有设置, 则显示0。

1.2.0:$remote_addr:存放了客户端的地址,注意是客户端的公网IP,也就是一家人访问一个网站,则会显示为路由器的公网IP,以下:

1.2.1:$remote_port:客户端请求Nginx服务器时随机打开的端口,这是每一个客户端本身的端口。

1.2.2:$remote_user:已经通过Auth Basic Module验证的用户名。

1.2.3:$request_body_file:作反向代理时发给后端服务器的本地资源的名称。

1.2.4:$request_method:请求资源的方式,GET/PUT/DELETE等

1.2.5:$request_filename:当前请求的资源文件的路径名称,由root或alias指令与URI请求生成。

/usr/local/nginx//html/web/

1.2.6:$request_uri:包含请求参数的原始URI,不包含主机名,如:”/index.do?id=101020100&partner=”。

/web/

1.2.7:$squery_string:保存了URL请求的指令,与 $args相同。

1.2.8:$scheme:请求的协议,如ftp,https,http等。

1.2.9:$server_protocpl:保存了客户端请求资源使用的协议的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等。

1.3.0:$server_addr:保存了服务器的IP地址。

192.168.0.24

1.3.1:$server_name:服务器的主机名。

hfnginx.chinacloudapp.cn

1.3.2:$server_port:服务器的端口号。

80

1.3.3:$uri:与$document_uri相同,是一个不包含指令的uri地址。

如访问:hfnginx.chinacloudapp.cn/index.do?id=101020100&partner=,uri以下:
/index.do

 

四:rewrite 功能的具体使用: 

nginx rewrite功能使用模块ngx_http_rewrite_module,rewrite是nginx服务器的重要模块之一,它一方面实现了URL的重写功能,另外一方面为Nginx服务器提供反向代理服务器的支持,使用以下:

一、proxy_pass:反向代理,将用户的请求代理至后端服务器:

server {
        server_name  hfnginx.chinacloudapp.cn;
        #access_log  logs/host.access.log  main;
        location / {
            root   html/hfnginx;
            index  index.html index.htm;
        }
        location /form/ {  #匹配一个访问的目录
            proxy_pass  http://192.168.0.201/bbs/;  #/form后面的斜杠要和http://192.168.0.201/bbs后面的斜杠要么都有要么都没有,不然访问匹配会出现错误。
  } }

1.1访问结果:

 1.2访问过程第一次是一个301(页面永久重定向)以下:

1.3访问过程第二次,返回页面的内容:

 

2.使用正则匹配访问页面:

server {
        server_name  hfnginx.chinacloudapp.cn;
        #access_log  logs/host.access.log  main;
        location / {
            root   html/hfnginx;
            index  index.html index.htm;
        }
        location ~* ^/form {
            proxy_pass  http://192.168.0.201;  #使用正则的话,http://192.168.0.201后面不支持加目录,不然语法错误,后端服务器Web的目录要和location设置的/form同名,不然报404页面找不到错误。 
} }

2.1:后端服务器的web目录:

[root@Server1 html]# ls
bbs
[root@Server1 html]# mv bbs form #将上一个例子中的bbs目录重命名成form,form对应locati的名称
[root@Server1 html]# ls
form

2.2:访问测试,步骤也是两次,一次301,一次正常页面:

 2.3:配置Nginx转发客户端IP:

        location ~* ^/form {
            proxy_pass  http://192.168.0.201;
            proxy_set_header X-Real-IP $remote_addr;
        }

2.4:http默认没法记录这个变量,所以要手动设置apache的日志格式:

[root@Server1 httpd]# vim /etc/httpd/conf/httpd.conf 
更改配置文件中日志格式的一行:
LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined #%{X-Real-IP}i表示是头部报文中某个变量的值,i是取值,取得是报文中X-Real-IP对应的值。这个值就是客户端的真实IP

2.5:从新访问并查看apache日志:

[root@Server1 httpd]# tail -n 1 /var/log/httpd/access_log 
47.88.87.169 - - [07/May/2016:19:39:43 +0800] "GET /form/ HTTP/1.0" 200 38 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36"

 

五:临时重定向与永久重定向:

1.防盗链:

referer是记录打开一个页面以前记录是从哪一个页面跳转过来的,若是别人只连接了本身网站图片或某个单独的资源,而不是网站的页面,这就是盗链,

location /image {
            valid_referers none blocked www.baidu.com;
    if ($invalid_referer) {
          return 403;
} #none是用户正常在浏览器输入地址访问的请求链接 #blocked 相似于防火墙法则,只要不符合给定条件的就认定是不合法的,就拒绝访问。

2.经过rewrite完成地址重写:

301:永久重定向,通常资源都在服务器内部,客户端请求一次便可完成数据的返回。

302:临时重定向,当nginx做为代理服务器,并使用rewrite重写用户请求的URL的到其余服务器的时候,就是临时重定向。

server {
        server_name  hfnginx.chinacloudapp.cn;
        location / {
            root   html;  #定义存放web的目录
            index  index.html;
            #rewrite ^/bbs/(.*)$  http://www.weather.com.cn/$1;  #将请求转发给其余服务器处理,是临时重定向,客户端须要在服务器返回报文中头部中查找到location字段并根据其中的路径到新服务器发送请求。
            rewrite ^/bbs/(.*)$   /web/$1;  #/web是在html目录下,也就是这里的跟就是html目录,将请求在服务器内存处理并返回给用户,是永久重定向的方式
        } 
}

2.1临时重定向请求过程以下:

2.2:永久重定向以下:

六:rewrite后面的四个flag:

1.last:本次重写完成以后,重启下一轮检查,大多数状况下使用last,可是若是匹配写的有问题,会致使出现循环匹配,直到十次以后出错。

2.break:本次完成重写以后,直接执行后续数据操做,再也不进行其余的条件匹配,在非跟location使用rewrite匹配的时候要使用break,避免致使循环。

3.redirect:返回302临时重定向,若是替换字段用http://开头则被使用。

4.permanent:返回301永久重定向。

 

七:对Apache实现上传下载分离:

 1.确认模块当中有dav模块:

LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule dav_lock_module modules/mod_dav_lock.so

二、打开dav功能:

<Directory "/var/www/html">
Dav on #加一行

三、重启httpd:

[root@Server1 html]# systemctl  restart  httpd

四、将www目录改成apache权限,并使用curl -T命令测试上传:

[root@Server1 html]# chown  apache:apache /var/www/html/ -R  #更改属主属组
[root@Server1 html]# curl -T  /etc/issue http://192.168.0.202  #上传一个文件
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>201 Created</title>
</head><body>
<h1>Created</h1>
<p>Resource /issue has been created.</p>  #返回上传成功
</body></html>

验证:

 [root@Server1 html]# ls /var/www/html/
    form index.html issue

五、客户端使用浏览器访问测试:

六、经过Nginx实现下载和上传的分离:

server {
        server_name  hfnginx.chinacloudapp.cn;
        location / {
            #root   html;
            index  index.html;
            proxy_pass  http://192.168.0.201;
            if ($request_method = "PUT"){  #假如请求的方法是上传
                proxy_pass  http://192.168.0.202;
                }
        }
}

七、测试上传是否生效:

八、服务器验证上传的文件:

 八:几个表明性的例子:

1.location匹配定义的目录:

location = / {  #精确匹配,/后面不能加任何字符串,符合此条件就直接返回数据,再也不像下匹配。
    if (-d $request_filename) {
         root /usr/local/nginx/html/;  #当用户访问newweb的时候,则显示此目录的内容,除此以外访问其余的任何目录都不匹配。
  [动做A]
}

location  / {
  # 由于全部的地址都以/开头,因此这条规则将匹配到全部请求,可是非精确匹配会采起正则和最长字符串会优先匹配,所以还会向下继续匹配,好比当访问/bbs的时候,还须要看下面是否更精确的匹配。
  [ 动做B] 
}
location
/documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合之后,还要继续往下搜索 # 若是后面的正则表达式都没有匹配到,就匹配这一条 [动做C] }
location
^~ /images/ { #匹配任何以/images/ 开头的任何请求而且中止搜索,后面任何正则表达式将不会被测试。 # 匹配任何以 /images/ 开头的地址,匹配符合之后,中止往下搜索正则,采用这一条。 [动做D] }
location
~* \.(gif|jpg|jpeg)$ { #~*为不区分大小写 # 匹配全部以 gif,jpg或jpeg 结尾的请求 # 然而,全部请求/images/下的图片会被动做D匹配处理,由于动做D有^~会优先匹配并终止匹配,因此到达不了这一条正则 [动做E] }
location
/images/ { # 字符匹配到 /images/,继续往下,会发现 ^~ 存在,若是动做D存在,则这一条就不生效。 [动做F] } location /images/abc { #最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在,若是D存在,则这一条就不生效。 #F与G的放置顺序是没有关系的 [动做G] } location ~ /images/abc/ { # 动做D存在,这一条不生效,若是注销动做D,则会优先最长匹配 动做G 开头的地址,而后向下匹配,到这一条的时候就会匹配并生效。 [ configuration H ] }
匹配优先级,顺序 no优先级: (location
=) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/) 上面的匹配结果 按照上面的location写法,如下的匹配示例成立: / -> config A 精确彻底匹配,即便/index.html也匹配不了 /downloads/download.html -> config B 匹配B之后,往下没有任何匹配,采用B /images/1.gif -> configuration D 匹配到F,往下匹配到D,中止往下 /images/abc/def -> config D 最长匹配到G,往下匹配D,中止往下 你能够看到 任何以/images/开头的都会匹配到D并中止,FG写在这里是没有任何意义的,H是永远轮不到的,这里只是为了说明匹配顺序 /documents/document.html -> config C 匹配到C,往下没有任何匹配,采用C /documents/1.jpg -> configuration E 匹配到C,往下正则匹配到E /documents/Abc.jpg -> config CC 最长匹配到C,往下正则顺序匹配到CC,不会往下到E

2.if判断语句:

if ($http_user_agent ~ MSIE) { #若是客户端是微软的IE浏览器,就将请求rewrite到msie目录下。
    rewrite ^(.*)$ /msie/$1 break;
} 

if ($http_cookie ~* "id=([^;]+)(?:;|$)") { # 若是cookie匹配正则,就设置变量$id等于正则引用部分
    set $id $1; 设置$id等于正则第一个括号内匹配的部分
 } 

if ($request_method = POST) { #若是提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
    return 405;
} 

if ($slow) { #限速,$slow能够经过 set 指令设置
    limit_rate 10k;
} 

if (!-f $request_filename){ #若是请求的文件名不存在,则反向代理到localhost 。这里的break也是中止rewrite检查
    break;
    proxy_pass  http://127.0.0.1; 
} 

if ($args ~ post=140){ #若是query string中包含"post=140",永久重定向到example.com
    rewrite ^ http://example.com/ permanent;
} 

三、关于防盗链:

location ~* \.(gif|jpg|png|swf|flv)$ { # 防盗链设置,对于后缀是gif、jgp等格式的生效
    valid_referers none blocked  a.com  *.a.com; #定义容许访问的请求连接
    if ($invalid_referer) {
        return 404;
    }
}

none:在浏览器输入网站域名直接访问的请求,须要容许访问的
blocked:有referer首部,可是referer首部被清除了,通常是防火墙改过的请求
server_name:带服务器名称的,通常是本机或其余服务器的请求,a.com和*.a.com是本公司的域名,要容许访问因而要先容许本机的访问,再禁止其余服务器的访问

4.实际使用建议:

实际使用中,我的以为至少有三个匹配规则定义,以下:
#直接匹配网站根,经过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也能够是一个静态首页
# 第一个必选规则
location = / {
    proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是nginx做为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,本身根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的状况不多了
location / {
    proxy_pass http://tomcat:8080/
}

若是其余能够精确匹配的路径,也能够精确匹配,这样会加快Nginx处理请求。

五、经常使用的正则匹配:

. : 匹配除换行符之外的任意字符
? : 重复0次或1次
+ : 重复1次或更屡次
* : 重复0次或更屡次
\d :匹配数字
^ : 匹配字符串的开始
$ : 匹配字符串的介绍
{n} : 重复n次
{n,} : 重复n次或更屡次
[c] : 匹配单个字符c
[a-z] : 匹配a-z小写字母的任意一个
小括号()之间匹配的内容,能够在后面经过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。

六、根据图片尺寸rewrite请求连接:

rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
#将
/images/bla_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。

七、域名重写:

server {
        server_name  hfnginx.chinacloudapp.cn; #凡是访问hfnginx.chinacloudapp.cn都会重定向到http://www.baidu.com
        location / {
        root   html;
        index  index.html;
        rewrite  ^/  http://www.baidu.com;
    } 
}

八、完整的例子引用:

http {
    # 定义image日志格式
    log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
    # 开启重写日志
    rewrite_log on;

    server {
        root /home/www;

        location / {
                # 重写规则信息
                error_log logs/rewrite.log notice; 
                # 注意这里要用‘’单引号引发来,避免{}
                rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
                # 注意不能在上面这条规则后面加上“last”参数,不然下面的set指令不会执行
                set $image_file $3;
                set $image_type $4;
        }

        location /data {
                # 指定针对图片的日志格式,来分析图片类型和大小
                access_log logs/images.log mian;
                root /data/images;
                # 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,若是还不在就跳转到最后一个url里
                try_files /$arg_file /image404.html;
        }
        location = /image404.html {
                # 图片不存在返回特定的信息
                return 404 "image not found\n";
        }
}
相关文章
相关标签/搜索