Nginx实现URL重写

一、什么是 URL 重写?

URL重写是指将一个URL请求重新写成网站可以处理的另一个URL的过程。 而为什么要修改URL呢?是为了安全,以及提高用户的体验。

  • URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如http://www.123.com/news/index.php?id=123 使用URLRewrite 转换后可以显示为 http://www.123.com/news/123.html
  • 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。
  • 实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com的
    80端口时,将其跳转到443端口。

二、重定向应用场景

  • 地址跳转:用户访问www.123.com这个URL是,将其定向至一个新的域名test.456.com
  • 协议跳转:用户通过http协议请求网站时,将其重新跳转至https协议方式,即80转443。
  • 伪静态:将动态页面显示为静态页面方式的一种技术, 伪静态技术是指展示出来的是以html一类的静态页面形式,但其实是用ASP一类的动态脚本来处理的。
  • 搜索引擎:SEO优化依赖于url路径, 通过对URL的一些优化,可以使搜索引擎更好的识别与收录网站的信息 。

三、重定向指令

Nginx Rewrite相关指令有 if、rewrite、set、return

3.1 if 指令

应用环境:server,location

(1)语法

if (condition) {}

if 可以支持如下条件判断匹配符号。

~ 					正则匹配 (区分大小写)
~* 				    正则匹配 (不区分大小写)
!~                  正则不匹配 (区分大小写)
!~*		            正则不匹配  (不区分大小写)
-f!-f 		    用来判断是否存在文件
-d!-d 		    用来判断是否存在目录
-e!-e 		    用来判断是否存在文件或目录
-x!-x 		    用来判断文件是否可执行

(2)Nginx的全局变量(可引用)

$args				请求中的参数;
$document_root	    针对当前请求的根路径设置值;
$host				请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$limit_rate			对连接速率的限制;
$request_method		请求的方法,比如"GET""POST";
$remote_addr		客户端地址;
$remote_port		客户端端口号;
$remote_user		客户端用户名,认证用;
$request_filename   当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images/a.jpg)
$request_uri		当前请求的文件路径名(不带网站的主目录/images/a.jpg)
$query_string$args相同;
$scheme				用的协议,比如http或者是https;
$server_protocol	请求的协议版本,"HTTP/1.0""HTTP/1.1";
$server_addr 		服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name		请求到达的服务器名;
$document_uri$uri一样,URI地址;
$server_port 		请求到达的服务器端口号;

(3)Rewrite flag
rewrite 指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记,支持的flag标记有:

标记作用
last相当于Apache里的[L]标记,表示完成rewrite,默认为last。
break本条规则匹配完成后,终止匹配,不再匹配后面的规则。
redirect返回302临时重定向,浏览器地址会显示跳转后的URL地址。
permanent返回301永久重定向,浏览器地址会显示跳转后URL地址。

permanent和redirect区别:

  • permanent
    对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。

  • redirect
    使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址栏不会更改。

3.2 rewrite 指令

(1)语法

rewrite   regex   replacement   [flag];
 重写     正则匹配    替换目标     标记(可选)

(2)示例

【示例1】

http://192.168.0.101/a/a.html ==> http://192.168.0.101/b/URL.gif

server {
   listen 80;
   server_name     localhost;
       location /a {
       root    /var/www/nginx;
       index   a.html index.htm;
       rewrite .* /b/URL.gif permanent;
     }
    location /b {
        root    /var/www/nginx;  #上传图片 URL.gif 到/var/www/nginx/b下
     }
}
  • 输入URL

    在这里插入图片描述

  • 输入URL后回车

    在这里插入图片描述

【示例2】

http://192.168.0.101/2019/a/a.html ==> http://192.168.0.101/2020/a/a.html

server {
   listen 80;
   server_name     localhost;
       location /2019/a {
       root    /var/www/nginx;
       index   a.html index.htm;
       rewrite ^/2019/(.*)$ /2020/$1 permanent;  #这里的$1表示取出第一个()里的值,即 a
     }
    location /2020/a {
        root    /var/www/nginx;  #上传图片 URL.gif 到/var/www/nginx/b下
     }
}
  • 输入URL

    在这里插入图片描述

  • 输入URL后回车

    在这里插入图片描述

【示例3】

http://www.zrsit.com/a/a.html ==> http://baidu.com/

server {
   listen 80;
   server_name     localhost;
       location /a {
       root    /var/www/nginx;
       index   a.html index.htm;
           if ($host ~* www.zrsit.com) {
           		rewrite .* http://www.baidu.com permanent;  #重写到baidu.com
           }
       }
}
  • 输入URL

    在这里插入图片描述

  • 输入URL后回车

    在这里插入图片描述

【示例4】

http://www.zrsit.com/a/a.html ==> http://baidu.com/a/a.html

server {
   listen 80;
   server_name     localhost;
       location /a {
       root    /var/www/nginx;
       index   a.html index.htm;
           if ($host ~* www.zrsit.com) {
           		rewrite .* http://www.baidu.com$request_uri permanent;  #重写到baidu.com/a/a.html。这里$request_uri为内置变量,取的是你访问域名 qf.com 的二级目录/a/1.html 的内容
           }
       }
}
  • 输入URL

    在这里插入图片描述

  • 输入URL后回车

    在这里插入图片描述

【示例5】

http://www.zrsit.com/login/a.html ==> http://www.zrsit.com/reg/a.html?user=a

server {
   listen 80;
   server_name     localhost;
   
       location /login {
       root    /var/www/nginx;
       index   a.html index.htm;   
       rewrite ^/login/(.*)\.html$ http://$host/reg/a.html?user=$1;  #$1为前面括号内容
       }
       location /reg {
       root    /var/www/nginx;
       index   a.html index.htm;   
       }
}
  • 输入URL

    在这里插入图片描述

  • 输入URL后回车

    在这里插入图片描述

3.3 set 指令

set 指令是用于定义一个变量,并且赋值。

应用环境:server、location、if

http://alice.test.com ==> http://www.test.com/tom
http://jack.test.com ==> http://www.test.com/jack

(1)本地域名解析

10.20.151.8 www.test.com
10.20.151.8 tom.test.com
10.20.151.8 jack.test.com

(2)编辑Nginx配置文件

[root@server-yum1 jack]# vim /etc/nginx/conf.d/test.conf
server {
    listen       80;
    server_name  www.test.com;

    location / {
         root   /var/www/nginx;
         index  index.html index.htm;
         if ( $host ~* ^www.test.com$) {
                break;   #当匹配到www.test.com时终止匹配
         }
         if ( $host ~* "^(.*)\.test\.com$" ) {
                set $user $1;
                rewrite .* http://www.test.com/$user permanent;   #当匹配到jack.test.com时,交给 “location /jack” 处理,匹配到tom.test.com时,交给 “location /tom” 处理。
         }
    }
    location /jack {
         root /var/www/nginx;
         index  jack.html index.hml;
    }
    location /tom {
         root /var/www/nginx;
         index tom.html index.hml;
    }
}

(3)添加测试数据

[root@nginx-server conf.d]# cd /var/www/nginx/
[root@nginx-server html]# mkdir jack tom
[root@nginx-server html]# echo "hello jack" >> jack/jack.html
[root@nginx-server html]# echo "hello tom" >> tom/tom.html

(4)浏览器端测试

在这里插入图片描述
在这里插入图片描述

3.4 return 指令

return 指令用于返回状态码给客户端。

应用环境:server、location、if

如果访问的.sh结尾的文件则返回403操作拒绝错误。

(1)Nginx配置

server {
    listen       80;
    server_name  www.testpm.cn;

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

    location ~* \.sh$ {
        return 403;
        }
}

(2)创建测试数据

[root@server-yum1 nginx]# cat index.html 
This is a test !!

(3)浏览器端访问www.test.com

在这里插入图片描述

当我访问以.sh结尾的文件www.test.com/123.sh时,会返回403状态码。

在这里插入图片描述

四、last 和 break 的区别

在3.1小节中已经提到了Rewrite flag,下面来看一下last、break的用法。

(1)Nginx配置

这里我使用的域名是www.test.com(我在上面已经进行过本地解析)

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /var/www/nginx;
        index  index.html index.htm;
    }
    location /break/ {  #当我匹配到www.test.com/break/时,给我重写到www.test.com/test/break.html 因其后标记为break,故匹配完后终止匹配。
        root   /var/www/nginx;
        rewrite .* /test/break.html break;
    }
    location /last/ {   #当我匹配到www.test.com/last/时,给我重写到www.test.com/test/last.html,因其后标记为last,故重新对server { … } 标签重新发起请求,这时就会匹配到www.test.com/test/test.html,匹配到这里时又因为其后有break,故匹配完后终止匹配。
        root   /var/www/nginx;
        rewrite .* /test/last.html last;
    }
    location /test/ {
        root   /var/www/nginx;
        rewrite .* /test/test.html break;
    }

}

(2)创建测试数据

[root@server-yum1 nginx]# pwd
/var/www/nginx
[root@server-yum1 nginx]# echo "last" > test/last.html
[root@server-yum1 nginx]# echo "break" > test/break.html
[root@server-yum1 nginx]# echo "test" > test/test.html

(3)浏览器端测试

  • 地址栏输入www.test.com时:

    在这里插入图片描述

  • 地址栏输入www.test.com/break/时:

    在这里插入图片描述

  • 地址栏输入www.test.com/last/时:

    在这里插入图片描述

last和break的区别:

  • last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求;
  • break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配;
  • 使用 proxy_pass 指令时,则必须使用break。
  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值