Nginx rewrite重写详解 #yyds干货盘点#

Posted 江晓龙的技术博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx rewrite重写详解 #yyds干货盘点#相关的知识,希望对你有一定的参考价值。

nginx rewrite地址重写

1.安装谷歌http status插件

做rewrite地址重新必须安装http status插件才能看到效果

1.从软件包中找到谷歌插件-http status.zip文件

2.打开谷歌浏览器点击设置---扩展程序---开发者模式


3.将zip包中想crx文件拖拽到扩展程序中安装即可,出现c表示安装成功

2.Rewrite基本概述

2.1.什么是rewrite

rewrite即url重写,主要实现url地址重写,以及重定向,就是把传入web的请求重定向到其他url的过程。比如访问baidu.com就会重定向到www.baidu.com。

2.2.Rewrite使用场景

2.2.1.url地址跳转

url地址跳转,例如用户访问old.com就会跳转到oldboy.com,或者当用户通过http的方式访问old.com时,就会跳转至https的方式访问oldboy.com

2.2.2.url伪静态

url伪静态,将动态页面显示为静态页面方式的一种技术,便于搜索引擎的录入,同时减少动态url地址对外暴露过多的参数,提升更高的安全性

2.2.3.SEO优化

搜索引擎SEC优化依赖于url路径,以便支持搜索引擎录入

2.2.4.用户方面

可以调整用户浏览的url,看起来更规范,合乎开发及产品人员的需求

3.Rewrite配置语法

3.1.Rewrite配置语法

  • 语法格式:rewrite regex replacement [flag];
  • 默认配置:--
  • 配置区域:server、localhost、if

3.2.rewrite匹配nginx全局变量

在匹配过程中可以应用一些Nginx的全局变量

例如:http://localhost:88/test1/test2/test.php
$host:localhost     //访问的域名
$server_port:88         //网站的端口号
$request_uri:/test1/test2/test.php          //网站路径
$document_root:/var/www/html        //网站在服务器的存放路径也就是server中的root
$request_filename:/var/www/html/test1/test2/test.php            //访问页面在服务器中的完整路径

更多变量

$args : #这个变量等于请求行中的参数,同$query_string
$content_length : 请求头中的Content-length字段。
$content_type : 请求头中的Content-Type字段。
$document_root : 当前请求在root指令中指定的值。
$host : 请求主机头字段,否则为服务器名称。
$http_user_agent : 客户端agent信息
$http_cookie : 客户端cookie信息
$limit_rate : 这个变量可以限制连接速率。
$request_method : 客户端请求的动作,通常为GET或POST。
$remote_addr : 客户端的IP地址。
$remote_port : 客户端的端口。
$remote_user : 已经经过Auth Basic Module验证的用户名。
$request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme : HTTP方法(如http,https)。
$server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name : 服务器名称。
$server_port : 请求到达服务器的端口号。
$request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri : 与$uri相同。

3.2.1.request_uri实例

 rewrite .* https://$server_name$request_uri;

3.3.Rewrite匹配优先级

1.执行server块的rewrite指令

2.执行location匹配

3.执行选定的location中的rewrite

4.Rewrite实例

4.1.开启Nginx的Rewrite日志功能

[root@localhost nginx]# vim nginx.conf
error_log  /var/log/nginx/error.log notice;     //设置错误日志级别为notice记录一些级别较低的日志
rewrite_log on;         //在http模块中加上

4.2.站点外跳转

实现访问jxl.wecenter.com就会跳转至www.baidu.com

1.在location中定义rewrite
[root@jxl ~]# vim /etc/nginx/conf.d/wecenter.conf
server 
        listen 80;
        server_name jxl.wecenter.com;
        access_log /nginx_log/jxl_wecenter_access.log main;

        location / 
                root /web/wecenter;
                index index.php index.html;
                rewrite ^/ https://www.baidu.com;       //表示以/开头的都会跳转到百度,访问网站首页就是/,在浏览器中输入jxl.wecenter.com没有加任何东西其实就是在访问网站的/,在日志中记录的也是/
        

        location ~ \\.php$ 
                root /web/wecenter;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        


2.重载nginx
[root@jxl conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@jxl conf.d]# systemctl reload nginx

3.日志输出
[root@jxl conf.d]# tail -f /var/log/nginx/error.log
这条输出表示用户访问的页面匹配了rewrite中的正则,以/开头
2020/04/25 20:59:12 [notice] 8818#8818: *47 "^/" matches "/", client: 192.168.81.1, server: jxl.wecenter.com, request: "GET / HTTP/1.1", host: "jxl.wecenter.com"
这条输出表示匹配成功后跳转到了"https://www.baidu.com"
2020/04/25 20:59:12 [notice] 8818#8818: *47 rewritten redirect: "https://www.baidu.com", client: 192.168.81.1, server: jxl.wecenter.com, request: "GET / HTTP/1.1", host: "jxl.wecenter.com"

如果访问的目录不存在会跳转rewrite指定的地址,如果存在则会跳转到真实页面

4.3.站点内跳转

用户访问/abc/index.html实际上访问的是/ccc/bbb/index.html

站点内跳转建议使用return,这样可以看到是从哪个页面跳转到哪个页面,而rewrite实现站点内跳转不会改变浏览器中输入的网址,对于用户来说相当于透明的。也可以使用rewrite的标签redirect实现。

  • 注意:站点内跳转在定义rewrite时后面必须跟上location中的路径,例如

    访问wecenter就跳转至know
    localtion ~ /wecenter 
    rewrite /wecenter /know
    

三种实现方式
首先准备内容
[root@jxl ~]# mkdir -p /web/ccc/bbb/
[root@jxl ~]# echo "cccbbb" > /web/ccc/bbb/index.html
1.绝对路径跳转
此种配置,只能实现访问/abc/index.html,如果访问/abc/Index.HTml的话就会报错,虽然location忽略大小写,但是rewrite中写死了/abc/index.html,rewrite的优先级要高于location的优先级
[root@jxl conf.d]# vim rewrite.conf
server 
        listen 80;
        server_name jxl.rewrite.com;
        root /web;
        index index.html;

        location ~* /abc/index.html 
                rewrite /abc/index.html /ccc/bbb/index.html;
        


2.任意路径跳转
这时访问/abc/index.html不管大小写都可以匹配
[root@jxl conf.d]# vim rewrite.conf
#rewrite
server 
        listen 80;
        server_name jxl.rewrite.com;
        root /web;
        index index.html;

        location ~* /abc/index.html 
                #rewrite /abc/index.html /ccc/bbb/index.html;
                rewrite .* /ccc/bbb/index.html;     //匹配任意字符然后跳转至/ccc/bbb/index.html
        


3.return方式实现
此方式可以实现访问/abc/index.html,跳转至/ccc/bbb/index.html
[root@jxl conf.d]# vim rewrite.conf
#rewrite
server 
        listen 80;
        server_name jxl.rewrite.com;
        root /web;
        index index.html;

        location ~* /abc/index.html 
                #rewrite /abc/index.html /ccc/bbb/index.html;
                #rewrite .* /ccc/bbb/index.html;
                return 302 /ccc/bbb/index.html;
        


4.rewrite加标记实现页面跳转
#rewrite
server 
        listen 80;
        server_name jxl.rewrite.com;
        root /web;
        index index.html;

        location ~* /abc/index.html 
                注意rewrite加了标记不要和return同时使用
                rewrite .* /ccc/bbb/index.html redirect;
                #return 302 /ccc/bbb/index.html;
        

4.4.站点内跳转-正则

实现访问http://jxl.rewrite.com/2018/ccc/bbb/index.html跳转到http://jxl.rewrite.com/2014/ccc/bbb/index.html

由于后半部分都一样,因此我们采用正则实现
[root@jxl conf.d]# vim rewrite.conf
server 
        listen 80;
        server_name jxl.rewrite.com;
        root /web;
        index index.html;

        location ~* /2018 
                rewrite ^/2018/(.*)$ /2014/$1 redirect;     //匹配以/开头也就是域名,后面跟一个2018目录在跟任意字符结尾的url跳转至/2014/$1 这个$1表示2018/写的内容
        

日志输出
2020/04/27 16:03:33 [notice] 15327#15327: *80 "^/2018/(.*)$" matches "/2018/ccc/bbb/index.html", client: 192.168.81.1, server: jxl.rewrite.com, request: "GET /2018/ccc/bbb/index.html HTTP/1.1", host: "jxl.rewrite.com"
2020/04/27 16:03:33 [notice] 15327#15327: *80 rewritten redirect: "/2014/ccc/bbb/index.html", client: 192.168.81.1, server: jxl.rewrite.com, request: "GET /2018/ccc/bbb/index.html HTTP/1.1", host: "jxl.rewrite.com"

4.5.站点内跳转-灵活正则

用户访问course-11-22-33.html实际上访问的是/course/11/22/33/course_33.html

[root@jxl ~]# mkdir -p /web/course/11/22/33/
[root@jxl ~]# echo "course_11_22_33" > /web/course/11/22/33/course_33.html
1.固定匹配,所有以course开头的文件都会跳转至/web/course/11/22/33/course_33.html页面
很显然这种方式不是很好
[root@jxl conf.d]# vim rewrite.conf
server 
        listen 80;
        server_name jxl.rewrite.com;
        root /web;
        index index.html;
                location / 
                rewrite ^/course-(.*) /course/11/22/33/course_33.html redirect;
        


2.灵活匹配,这样一来会根据访问的文件名自动跳转至对应的页面
server 
        listen 80;
        server_name jxl.rewrite.com;
        root /web;
        index index.html;

        location / 
                rewrite ^/(.*)-(.*)-(.*)-(.*).html$ /$1/$2/$3/$4/$1_$4.html redirect;
        

访问http://jxl.rewrite.com/course-11-22-33.html

扩展,再来一个页面
[root@jxl conf.d]# mkdir -p /web/sports/55/66/77
[root@jxl conf.d]# echo "sports_55_66_77" > /web/sports/55/66/77/sports_77.html
访问http://jxl.rewrite.com/sports-55-66-77.html

jxl.rewrite.com/course-11-22-33.html效果

jxl.rewrite.com/sports-55-66-77.html效果

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200524144613838.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDk1MzY1OA==,size_16,color_FFFFFF,t_70)

4.6.http请求跳转至https

server 
    listen 80;
    server_name jxl.rewrite.com;
    rewrite ^(.*) https://$server_name$1 redirect;
    #return 302 https://$request_uri;


server 
    listen 443;
    server_name jxl.rewrite.com;
    ssl on;

5.Rewrite标记Flag

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

last 本条规则匹配完成后继续向下匹配新的location URI规则
break 本条规则匹配完成后终止,不在匹配任何规则
redirect 返回302临时重定向,地址栏会显示跳转后的地址
parmanent 返回301永久重定向,地址栏显示跳转后的地址

5.1.permament实例

permanent永久重定向,即使清除浏览器缓存都无法清除,每次访问链接都会跳转至该页面。

[root@jxl conf.d]# vim rewrite.conf 
server 
        listen 80;
        server_name jxl.rewrite.com;
        index index.html;
        root /web;

        location / 
                rewrite ^/(.*)-(.*)-(.*)-(.*).html$ /$1/$2/$3/$4/$1_$4.html permanent;
        
        

[root@jxl conf.d]# systemctl restart nginx
页面访问会看到301

停到nginx,会发现页面依旧可以访问到
[root@jxl conf.d]# systemctl stop nginx

5.2.redirect实例

redirect临时重定向

[root@jxl conf.d]# vim rewrite.conf 
server 
        listen 80;
        server_name jxl.rewrite.com;
        index index.html;
        root /web;

        location / 
                rewrite ^/(.*)-(.*)-(.*)-(.*).html$ /$1/$2/$3/$4/$1_$4.html permanent;
        
 

  • 访问jxl.rewrite.com/wecenter跳转至jxl.rewrite.com/knoe

    [root@jxl conf.d]# vim rewrite.conf 
    server 
          listen 80;
          server_name jxl.rewrite.com;
          index index.php index.html;
          root /web;
        location /wecenter 
                  rewrite ^/wecenter /know redirect;
          
    
    

5.3.last/break实例

last与break对比总结

last
last匹配成功后会继续向下匹配location中url
1.last进行rewrite匹配成功,停止当前这个请求,并根据rewrite匹配的规则重新向server发起一个请求。,也就是匹配成功再重新发一个请求
2.新的请求的内容是域名+URL对应的地址为jxl.rewrite.com/2017_old

break
1.break进行rewrite匹配后不会像last重新发起请求,首先查找站点目录下/web/2018_old是否存在目录,如果不存在则报错404,如存在继续往下匹配,也就是说会事先查看跳转路径下是否存在默认页面,如果存在就直接显示,如果不存在则报错。
2.根据Rewrite匹配的规则,跳转至jxl.rewrite.com/2017_old的URL地址,匹配成功后则不继续匹配

last/break实例

last与break对比总结

last
last匹配成功后会继续向下匹配location中url
1.last进行rewrite匹配成功,停止当前这个请求,并根据rewrite匹配的规则重新向server发起一个请求。,也就是匹配成功再重新发一个请求
2.新的请求的内容是域名+URL对应的地址为jxl.rewrite.com/2017_old

break
1.break进行rewrite匹配后不会像last重新发起请求,首先查找站点目录下/web/2018_old是否存在目录,如果不存在则报错404,如存在继续往下匹配,也就是说会事先查看跳转路径下是否存在默认页面,如果存在就直接显示,如果不存在则报错。
2.根据Rewrite匹配的规则,跳转至jxl.rewrite.com/2017_old的URL地址,匹配成功后则不继续匹配

以上是关于Nginx rewrite重写详解 #yyds干货盘点#的主要内容,如果未能解决你的问题,请参考以下文章

Nginx URL重写(rewrite)配置及信息详解

Nginx URL重写(rewrite)配置及信息详解

Nginx正则表达式location匹配Rewrite重写详解

Nginx Rewrite语法详解

Nginx动静分离详解以及配置 #yyds干货盘点#

Nginx四层负载均衡详解 #yyds干货盘点#