Nginx Rewrite

一、Nginx Rewrite 概述

1.Rewrite 跳转场景

  • 可以调整用户浏览的 URL,看起来更规范,合乎开发及产品人员的需求。
  • 为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态 URL 地址伪装成静态地址提供服务。

  • 网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的 360buy.com 会跳转到 jd.com

  • 根据特殊变量、目录、客户端的信息进行 URL 调整等。

2.Rewrite 跳转实现

        Nginx 是通过 ngx_http_rewrite_module 模块支持 url 重写、支持 if 条件判断,但不支持 else。另外该模块需要 PCRE 支持,应在编译 Nginx 时指定 PCRE 支持,默认已经安装。

3.Rewrite 实际应用场景

        在实际工作的应用中,Nginx 跳转需求有三种方式可实现。可以直接用 rewrite 进行匹配跳转,也可以使用 if 匹配全局变量后跳转。另外,还可以使用 location 匹配再跳转。

4.Nginx正则表达式

二、Nginx Rewrite 基本操作

2.1Location 分类

location 大致可以分为三类,语法如下:

location = patt {} [精准匹配]

location patt {} [一般匹配]

location ~ patt {} [正则匹配]

[root@localhost ~]# mkdir -p /var/www/html/aaa
[root@localhost ~]# mkdir -p /var/www/html/bbb
[root@localhost ~]# mkdir -p /var/www/html/ccc

[root@localhost ~]# echo "aaa">/var/www/html/aaa/aaa.html
[root@localhost ~]# echo "bbb">/var/www/html/bbb/index.html
[root@localhost ~]# echo "ccc">/var/www/html/ccc/INDEX.html
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
location / {
            root   /var/www/html/aaa;
            index  index.html aaa.html;
        }

        location = /index.html {
            root   /var/www/html/bbb;
            index  index.html index.htm;
        }

        location ~ /INDEX.html {
            root   /var/www/html/ccc;
            index  index.html index.htm INDEX.html;
        }

备注:

http://192.168.10.101

  • 访问到的是aaa

http://192.168.10.101/index.html

访问到的是bbb

http://192.168.10.101/INDEX.html

访问到的是ccc

2.2Location 优先级

        在 Nginx location 配置中 location 的顺序没有太大关系。匹配优先级和 location 表达式的类型有关:相同类型的表达式,字符串长的会优先匹配。

以下是按优先级排列说明:

  • 等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
  • ^~类型表达式。一旦匹配成功,则不再查找其他匹配项。
  • 正则表达式类型(~~*)的优先级次之。
  • 常规字符串匹配类型。按前缀匹配。
  • 通用匹配(/),如果没有其它匹配,任何请求都会匹配到。

备注:

  • = 严格匹配。如果这个查询匹配,那么将停止搜索并立即处理此请求。
  • ~ 区分大小写匹配(可用正则表达式)
  • !~区分大小写不匹配
  • ~* 不区分大小写匹配(可用正则表达式)
  • !~*不区分大小写不匹配
  • ^~ 如果把这个前缀用于一个常规字符串,那么告诉nginx 如果路径匹配那么不测试正则表达式。

很多情况下 rewrite 也会写在 location 里,它们的执行顺序如下:

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

#精确匹配 / ,主机名后面不能带任何字符串
location = / { 
[ configuration A ] 
}
# 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求,但是正则和最长字符串会优先匹配
location / { 
[ configuration B ] 
}
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续向下搜索,只有后面的正则表达式没有匹配到时,这一条才会起作用 
location /documents/ { 
[ configuration C ] 
}
# 匹配任何以 /documents/abc 开头的地址,匹配符合以后,还要继续向下搜索,只有后面的正则表 
达式没有匹配到时,这一条才会起作用 
location ~ /documents/abc { 
[ configuration D ] 
}
# 匹配任何以 /images/ 开头的地址,匹配符合以后,停止向下匹配 
location ^~ /images/ { 
[ configuration E ] 
}
# 匹配所有以 gif,jpg 或 jpeg 结尾的请求,然而所有请求/images/下的图片会被 [ configuration E] 处理,因为^~的优先级更高 
location ~* \.(gif|jpg|jpeg)$ { 
[ configuration F ] 
}
# 最长字符匹配到 /images/abc,优先级最低 
location /images/abc { 
[ configuration G ] 
}
# 匹配以/images/abc 开头的,优先级次之 
location ~ /images/abc { 
[ configuration H ] 
}
# 匹配/images/abc/1.html 文件,如果和正则~ /images/abc/1.html 相比,正则优先级更高
location /images/abc/1.html { 
[ configuration I ] 
}

总结:

如果是匹配某个具体文件

(location = 完整路径) > (location ^~ 完整路径) > (location ~* 完整路径)> (location ~ 完整路径) > (location 完整路径) > (location /)

如果是用目录做匹配访问某个文件

(location = 目录) > (location ^~ 目录/) > (location ~ 目录)> (location ~* 目录) > (location 目录) > (location /)

2.3Rewrite 常见示例

1.案例环境

  • 192.168.10.101 www.benet.com 
  • 192.168.10.102 www.accp.com

设置好客户端和服务器端的hosts文件

要求:访问www.benet.com,跳转到www.accp.com

2.修改 Nginx 默认站点配置文件

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
    server {
        listen       80;
        server_name  www.benet.com;

        charset utf-8;

        #access_log  logs/host.access.log  main;

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

3.Rewrite 示例

(1)基于域名的跳转
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
server {
        listen       80;
        server_name  www.benet.com;

        charset utf-8;

        #access_log  logs/host.access.log  main;

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

        if ($host = 'www.benet.com') 
          {
          rewrite ^/(.*)$ http://www.accp.com/$1 permanent; 
          }

    }
}
  • 备注:
  • $host = 'www.benet.com'  判断获取到得请求URL是否为www.benet.com     另外,=号两边有空格permanent:返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址,爬虫更新 url,没有则返回302。
  • ^/(.*)$
  • ^  指的是以任何字符或字符串开始的域名都会匹配上
  • /  指得是url后跟的/,比如www.benet.com/index.html
  • .*  匹配任意多个字符,注意这里的(),括号里的内容会用后面的$1调用
  • $   结尾
  • 备注:
  • Rewrite 语法
  • rewrite<regex><replacement>[flag];
  • flag 标记说明:
  • last:相当于 Apache 的[L]标记,表示完成 rewrite。
  • break:本条规则匹配完成即终止,不再匹配后面的任何规则。
  • redirect:返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址,爬虫不会更新url(因为是临时)。
  • permanent:返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址,爬虫更新 url。
[root@localhost ~]# systemctl restart nginx
  • a:域名直接跳转
  • F12 可以清楚的看到从旧域名 www.benet.com 跳转到了新域名 www.accp.com 上,状态码是 301 永久重定向
  • b:域名后面加参数跳转

  • 备注:
  • 匹配规则
  • ~:表示执行一个正则匹配,区分大小写。
  • ~*:表示执行一个正则匹配,不区分大小写。
  • !~:表示执行一个正则匹配,区分大小写不匹配。
  • !~*:表示执行一个正则匹配,不区分大小写不匹配。
  • ^~:表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他 location
  • =:进行普通字符精确匹配,也就是完全匹配。
  • @:它定义一个命名的 location,使用在内部定向时,例如 error_page, try_files
(2)基于客户端 IP 访问跳转

        要求所有外部IP访问任何内容都显示一个固定维护页面,只有公司内部IP 访问正常假设内部IP为192.168.10.103,外部IP为192.168.10.105

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf

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

    #access_log  /var/log/nginx/host.access.log  main;

    set $rewrite true;
    if ($remote_addr = "192.168.10.51") {
        set $rewrite false;
    }
    if ($rewrite = true) {
    rewrite (.+) /maintenance.html;
    }

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

#	if ($host = 'www.benet.com') 
#	  {
#	  rewrite ^/(.*)$ http://www.accp.com/$1 permanent; 
#	  }
    }
}
  • 备注:
  • (.+)  匹配整个URL,匹配上以后,就在URL后面加上/maintenance.html
  • .+  匹配任意字符1次或多次
  • .*  匹配任意字符0次或多次
[root@localhost ~]# systemctl restart nginx
[root@localhost ~]# echo "Website is Maintaining,Please visit later."> /usr/local/nginx/html/maintenance.html

先用客户端192.168.10.51访问,能正常访问www.benet.com,再用其他IP客户端访问,打开的是maintenance.html页面

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

访问http://bbs.benet.com/post时,需要将这个域名跳转到http://www.benet.com/bbs/post

[root@localhost html]# cd /usr/local/nginx/html/
[root@localhost html]# mkdir -p bbs/post
[root@localhost html]# cd bbs/post
[root@localhost post]# echo "i am bbs">index.html
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
server {
    listen       80;
    server_name  bbs.benet.com;

    #access_log  /var/log/nginx/host.access.log  main;

    location /post {
        rewrite (.+) http://www.benet.com/bbs$1 permanent;
    }

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

}
}

[root@localhost ~]# systemctl restart nginx
  • 客户端添加域名解析
  • 192.168.10.101 bbs.benet.com
  • 在客户端浏览器地址栏输入 http://bbs.benet.com/post,会跳转到http://www.benet.com/bbs/post/
  • 备注:
  • 如果需要将bbs.benet.com的域名重写为www.benet.com/bbs
  • 则使用如下配置:
    server {
        listen       80;
        server_name  bbs.benet.com;
    
        #access_log  /var/log/nginx/host.access.log  main;
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
    
    
    if ($host = 'bbs.benet.com')
    {
    rewrite ^/(.*)$ http://www.benet.com/bbs/$1 permanent;
    }
        }
    }
    (4)基于参数匹配的跳转
  • 在访问 http://www.benet.com/100-(100|200)-100.html 跳转到 http://www.benet.com页面

    [root@localhost post]# vim /usr/local/nginx/conf/nginx.conf
    server {
        listen       80;
        server_name  bbs.benet.com;
    
        #access_log  /var/log/nginx/host.access.log  main;
    
        if ($request_uri ~ ^/100-(100|200)-(\d+).html$) {
            rewrite (.*) http://www.benet.com permanent;
        }
    
        location / {
            root   html;
            index  index.html index.htm;
    
    }

    备注:

    \d+  匹配任意个数字

    [root@localhost ~]# systemctl restart nginx

    使用浏览器访问 http://www.benet.com/100-100-100.html,会跳转到http://www.benet.com

  • (5)基于目录下所有 php 结尾的文件跳转

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

[root@localhost post]# vim /usr/local/nginx/conf/nginx.conf
server {
    listen       80;
    server_name  bbs.benet.com;

    #access_log  /var/log/nginx/host.access.log  main;

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

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

    }
}

备注:

~*  不区分大小写

~   区分大小写

.*\.php  一个文件的名字   名字.后缀   任意名字.php

[root@localhost ~]# systemctl restart nginx

浏览器访问 http://www.benet.com/upload/1.php会跳转到http://www.benet.com

(6)基于最普通一条 url 请求的跳转
[root@localhost post]# vim /usr/local/nginx/conf/nginx.conf

server {
    listen       80;
    server_name  bbs.benet.com;
    
    #access_log  /var/log/nginx/host.access.log  main;


    location ~* ^/1/test.html {
        rewrite (.+) http://www.benet.com permanent; 
    }   

    location / {
        root   html;
        index  index.html index.htm;
    }
[root@localhost ~]# systemctl restart nginx

浏览器访问 http://www.benet.com/1/test.html 跳转到http://www.benet.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值