Nginx 重写功能

location模块

官方文档

http://nginx.org/en/docs/http/ngx_http_core_module.html#directives

1.Nginx常见模块

  • http

    http块是Nginx服务器配置中的重要部分,代理、缓存和日志定义等绝大多数的功能和第三方模块的配置都可以放在这模块中。作用包括:文件引入、MIME-Type定义、日志自定义、是否使用sendfile传输文件、连接超时时间、单连接请求数上限等。

  • server

    server块,虚拟主机(虚拟服务器)。作用:使得Nginx服务器可以在同一台服务器上只要运行一组Nginx进程,就可以运行多个网站。

  • location

    location块是server块的一个指令。作用:基于Nginx服务器接收到的请求字符串,虚拟主机名称(ip,域名)、url匹配,对特定请求进行处理。

2.location

2.1一般分为普通和正则

常用的正则表达式

字符含义
.匹配任意单个字符,可以是一个汉字
^行首锚定, 用于模式的最左侧
$行尾锚定,用于模式的最右侧
*匹配前面字符任意次(包括0次)
?0或1次
+1次或多次(1次或以上)
\转义符
\d只匹配数字
{n}重复n次
{n,}至少n次(n次货以上)
{n,m}n到m次
[ ]定义匹配字符的范围,只匹配一次
[c]单个字符
[a-z]匹配任意小写字母
[a-zA-Z0-9]匹配任意字母和数字
()表达式的开始和结束位置
|或运算符a|b
从功能看 rewrite 和 location 似乎有点像,都能实现跳转,主要区别在于 rewrite 是在同
一域名内更改获取资源的路径,而 location 是对一类路径做控制访问或反向代理,还可以
proxy_pass 到其他机器。

location:
精确匹配:location = /  {.....}
一般匹配:location  /  {.....}
正则匹配:location ~ / {.....}

2.2 location 常用的匹配规则

规则表达式规则含义
=进行普通字符精确匹配。也就是完全匹配
^~表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他 location
~表示执行一个正则匹配,区分大小写
~*表示执行一个正则匹配,不区分大小写
!~表示执行一个正则匹配,区分大小写不匹配
!~*表示执行一个正则匹配,不区分大小写不匹配

2.3 location优先级排列说明:

  1. 等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
  2. ^~类型表达式。一旦匹配成功,则不再查找其他匹配项。
  3. 正则表达式类型(*)的优先级次之。常规字符串匹配类型(不带任何修饰符的匹配),按前缀匹配。/test
  4. 通用匹配(/),如果没有其它匹配,任何请求都会匹配到。
location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

2.4 location 示例

(1)精确匹配

location = / {}
=为精确匹配 / , 主机名后不能携带任何字符串,比如 / 和 /data ,则/匹配,/data不匹配
举例:

(2)一般匹配/通用匹配

location  / {}
代表已/开头,所以这条规则将匹配所有的请求     /
location  /documents/ {}
匹配任何已/documents/开头的地址,匹配符合后,还会继续往下搜索其他 location,只有其它location后面的正则表达式没有匹配到时,才会用这一条

location  /documents/abc {} 
匹配任何已/documents/abc开头的地址,匹配符合后,还会继续往下搜索其他 location,只有其它location后面的正则表达式没有匹配到时,才会用这一条

(4)正则匹配

location ^~ /images/ {} 
匹配任何已/images/ 开头的地址,匹配符合后,停止往下搜索,采用这一条


location ~* \.(gif|jpg|jpeg)$ {} 
匹配所有 gif jpg 或 jepg 结尾的请求
如果 有上面的location ^~ /images/ {}匹配  则会先匹配上一请求,所以到不了这一条。

location 优先级总结:

1. 如果是匹配某个具体文件:
(location = 完整路径) > (location ^~ 完整路径) > (location ~* 完整路径) >(location ~ 完整路径)  > (location /)通用匹配

实际例子

 location / {
            root   html;
            index  index.html index.htm;
        }

        location = / {
            root   /web/cat/;
        }

###第一次匹配只写域名精确匹配不生效

     location / {
            root   html;
            index  index.html index.htm;
        }

        location = /index.html {
            root   /web/cat/;
        }
###在 根后 加上index.html 后生效


###例子2
		location = /1.jpg {
            root   /web/cat/;
        }

        location ~* \.(gif|jpg|png|jpeg)$ {
           root   /web/dog/;
        }


###大小写问题
location ~ /A.?\.jpg {
            root   /web/image;
            index  index.html index.htm;
        }

location ~* /A.?\.jpg {
            root   /web/image;
            index  index.html index.htm;
        }

实际网站使用中,至少有三个匹配规则定义

第一个规则

直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。

可以是一个静态首页,也可以直接转发给后端应用服务器

location = / {
	root html;
	index index.html index.htm;
	}

第二个规则

是处理静态文件请求,这是nginx作为http服务器的强项有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用

location ^~ /static/ {
       root /webroot/static/ ;
}      

location ~* \.(gif|jpg|jpeg)$ {
      root /webroot/static/ ;
}

第三个规则

就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器。

location  / {
       proxy_pass http://tomcat_server;
}      

1REWRITE模块

现在 Nginx 已经成为很多公司作为前端反向代理服务器的首选,在实际工作中往往会
遇到很多跳转(重写 URL)的需求。比如更换域名后需要保持旧的域名能跳转到新的域名
上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。如果在后端使用的 Apache
服务器,虽然也能做跳转,规则库也很强大,但是用 Nginx 跳转效率会更高,这也是学习
本章的目的所在。

1.1rewrite功能

rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。

rewrite 只能在
server {}
location {}
if {}
中,并且默认只能对域名后边的除去传递的参数外的字符串起作用
例如:
http://www.kgc.com/abc/bbs/index.html?a=1&b=2 只针对/abc/bbs/index.html重写

1.2Rewrite 跳转场景

Rewrite 跳转场景主要包括以下几种

  1. 可以调整用户浏览的 URL,看起来更规范,合乎开发及产品人员的需求
  2. 为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态 URL 地址伪装成静态地址提供服务
  3. 网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的 360buy.com会跳转到 jd.com
  4. 根据特殊变量、目录、客户端的信息进行 URL 调整等。

1.3Rewrite 跳转实现

​ Nginx 是通过 ngx_http_rewrite_module 模块支持 url 重写、支持 if 条件判断,但不支
持 else。

另外该模块需要 PCRE 支持,应在编译 Nginx 时指定 PCRE 支持,默认已经安装。

根据相关变量重定向和选择不同的配置,从一个 location 跳转到另一个 location,不过这样
的循环最多可以执行 10 次,超过后 Nginx 将返回 500 错误。

同时,重写模块包含 set 指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。

1.4Rewrite 执行顺序如下

rewrite执行顺序如下:

  1. 执行server块里面的rewrite指令。
  2. 执行location 匹配。
  3. 执行选定的location中的rewrite指令。

1.5语法格式

rewrite <regex> <replacement> [flag];
regex:表示正则匹配规则
replacement:表示跳转后的内容
flag:表示rewrite 支持的 flag 标记

flag 标记说明:
last:本条规则匹配完成后,继续向下匹配新的location URL规则,一般用在server和if中

break:本条规则匹配完成即终止,不再匹配后面的任何规则。一般用在location中

redirect:返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址,爬虫不会更新 url(因为是临时)。

permanent:返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址,爬虫更新 url。

1.6 Rewrite举例

1.6.1

基于旧域名跳转到新域名后面加目录,例如现在访问的是 http://www.kgc.com,
现在需要将这个域名下面的发帖都跳转到 http://www.benet.com,注意保持域名跳转
后的参数不变。

[root@localhost nginx]#cd html/
[root@localhost html]#mkdir test
[root@localhost html]#echo "this is test web" >test/index.html

去真机访问http://www.kgc.com/test/index.html


server {
        listen       80;
        server_name  www.kgc.com;

        charset utf-8;

        #access_log  logs/host.access.log  main;

        location / {
            if ($host = 'www.kgc.com'){
            #$host为Rewrite全局变量,代表请求主机头字段或主机名
            rewrite ^/(.*)$ http://www.benet.com/$1 permanent;
            #$1为正则匹配内容,即域名/后之后的字符串
            }
            root   html;
            index  index.html index.htm;
        }



server {
        listen       80;
        server_name  www.kgc.com;

        charset utf-8;

        access_log  logs/www.kgc.com.log;

        location / {
        if ($host = 'www.kgc.com'){
        rewrite ^/(.*)$ http://www.benet.com/$1 permanent;
        }
            root   html;
            index  index.html index.htm;
        }


1.6.2.基于客户端IP 访问跳转

server {
        listen       80;
        server_name  www.kgc.com;

        charset utf-8;

        access_log  logs/www.kgc.com.log ;
 		
 		###设置是否合法的IP标识###
        set $rewrite true;    
        
        ###判断是否合法的ip###
        if ($remote_addr = "192.168.91.103") {                                
        #当客户端IP为192.168.91.103时将变量值设为false,不进行重写
        set $rewrite false;                                                             }                           
 		 if ($rewrite = true) {                                                          rewrite (.+) /weihu.html;                                                          
        } 
		location = /weihu.html {
            root   /var/www.html;
        }
        
        location / {
            root   html;
            index  index.html index.htm;
        }



 set $rewrite true;
        if ($remote_addr = 192.168.91.103) {
        set $rewrite false;
        }
        if ( $rewrite = true ){
        rewrite (.+) /weihu.html;
}
        location /weihu.html {
            root   /var/www/html;

        }


1.6.3基于旧域名跳转到新域名后面加目录

例如现在访问的是 http://bbs.kgc.com/post
现在需要将这个域名下面的发帖都跳转到 http://www.kgc.com/bbs/post,注意保持域名跳转
后的参数不变。

server {
        listen       80;
        server_name  bbs.kgc.com;

        charset utf-8;

        access_log  logs/www.kgc.com.log;
        
 		location /post {
            rewrite (.+) http://www.kgc.com/bbs/$1 permanent;
				#$1为位置变量,代表/post
        }
        
[root@localhost html]#mkdir -p bbs/post
[root@localhost html]#vim bbs/post/index.html

1.6.4基 于 参 数 匹 配 的 跳 转

http://www.kgc.com/100-(100|200)-100.html 跳转到 http://www.kgc.com 页面

http://www.kgc.com/100-(100|200)-100.html
http://www.kgc.com/100-100-100
http://www.kgc.com/100-200-100

server {
        listen       80;
        server_name  www.kgc.com;                    ###改域名

        charset utf-8;                                             ###改字符集

        #access_log  

        if ($request_uri ~ ^/100-(100|200)-(\d+).html$) {
        rewrite (.*) http://www.kgc.com permanent;
        }
      
      location ~ /100-(100|200)-(\d+).html${
       rewrite (.+) http://www.kgc.com permanent;
       }

1.6.5基于 目录下所有的php文件

要求访问 http://www.kgc.com/upload/123.php 跳转到首页

location ~* /upload/.*\.php${
       rewrite (.+) http://www.kgc.com permanent;
       }

1.6.6基于 普通的一条url

要求访问一个具体的页面 如 http://www.kgc.com/abc/123.html 跳转到首页

location ~* ^/abc/123.html${
       rewrite (.+) http://www.kgc.com permanent;
       }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值