nginx的rewrite

rewrite中的break和last

两个指令用法基本相同,但含义不同,需要放到rewrite规则的末尾,用来控制重写后的链接是否继续被nginx配置执行(主要是rewrite、return指令)。

编辑www.1.com.conf


[root@k8s-node01 vhost]# vi www.1.com.conf
server {

       listen 80;
       server_name www.1.com;
       root /data/wwwroot/www.1.com;
       rewrite_log on;
       rewrite /1.html /2.html;
       rewrite /2.html /3.html;
       }

 创建html文件

[root@k8s-node01 conf]# cd /data/wwwroot/www.1.com/
[root@k8s-node01 www.1.com]# vi 1.html
[root@k8s-node01 www.1.com]# vi 2.html
[root@k8s-node01 www.1.com]# vi 3.html

访问

[root@k8s-node01 vhost]# /usr/local/nginx/sbin/nginx -s reload
[root@k8s-node01 www.1.com]# curl -x127.0.0.1:80 www.1.com/1.html
333333333333333333

查看错误日志,最终访问到3.html

7.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:24:40 [notice] 16573#0: *2 rewritten data: "/2.html", args: "", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:24:40 [notice] 16573#0: *2 "/2.html" matches "/2.html", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:24:40 [notice] 16573#0: *2 rewritten data: "/3.html", args: "", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"

加上break

server {

       listen 80;
       server_name www.1.com;
       root /data/wwwroot/www.1.com;
       rewrite_log on;
       rewrite /1.html /2.html;break;
       rewrite /2.html /3.html;
       }

[root@k8s-node01 vhost]# /usr/local/nginx/sbin/nginx -s reload
[root@k8s-node01 vhost]# curl -x127.0.0.1:80 www.1.com/1.html
22222222
#访问到2结束
#在这里break改为last效果一样
#当在local中使用时不一样

location

server {

       listen 80;
       server_name www.1.com;
       root /data/wwwroot/www.1.com;
       rewrite_log on;
       location / {
           rewrite /1.html /2.html;
           rewrite /2.html /3.html;
       }
       location /2.html {
           rewrite /2.html /a.html;
       }
       location /3.html {
           rewrite /3.html /b.html;
       }

  }

[root@k8s-node01 logs]# curl -x127.0.0.1:80 www.1.com/1.html
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
2019/08/21 21:45:08 [notice] 16917#0: *6 "/1.html" matches "/1.html", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:45:08 [notice] 16917#0: *6 rewritten data: "/2.html", args: "", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:45:08 [notice] 16917#0: *6 "/2.html" matches "/2.html", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:45:08 [notice] 16917#0: *6 rewritten data: "/3.html", args: "", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:45:08 [notice] 16917#0: *6 "/3.html" matches "/3.html", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:45:08 [notice] 16917#0: *6 rewritten data: "/b.html", args: "", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:45:08 [notice] 16917#0: *6 "/1.html" does not match "/b.html", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:45:08 [notice] 16917#0: *6 "/2.html" does not match "/b.html", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:45:08 [error] 16917#0: *6 open() "/data/wwwroot/www.1.com/b.html" failed (2: No such file or directory), client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
#//进入根,/1.html匹配到规则/1.html,转到/2.html。/2.html匹配到规则/2.html,转到/3.html。
#//3.html匹配到location /3.html,转到/b.html。/b.html跳出来进入根试图匹配规则/1.html,/2.html
#//最后报错

加break

server {

       listen 80;
       server_name www.1.com;
       root /data/wwwroot/www.1.com;
       rewrite_log on;
       location / {
           rewrite /1.html /2.html;break;
           rewrite /2.html /3.html;
       }
       location /2.html {
           rewrite /2.html /a.html;
       }
       location /3.html {
           rewrite /3.html /b.html;
       }

  }


[root@k8s-node01 vhost]# /usr/local/nginx/sbin/nginx -s reload
[root@k8s-node01 vhost]# curl -x127.0.0.1:80 www.1.com/1.html
22222222
#访问到www.2.com
2019/08/21 21:59:17 [notice] 17201#0: *7 "/1.html" matches "/1.html", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
2019/08/21 21:59:17 [notice] 17201#0: *7 rewritten data: "/2.html", args: "", client: 127.0.0.1, server: www.1.com, request: "GET HTTP://www.1.com/1.html HTTP/1.1", host: "www.1.com"
#即遇到break后面不再执行,如果改为last本次location不再执行,但后面依旧执行

rewrite中return

#//返回状态码
[root@k8s-node01 vhost]# vi default.conf 

server {

      listen 80 default_server;
        return 403;
       }
                                                                                  
             
[root@k8s-node01 vhost]# curl -x127.0.0.1:80 dlfkakf 
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
#//if中使用
[root@k8s-node01 vhost]# vi www.1.com.conf
server {

       listen 80;
       server_name www.1.com;
       root /data/wwwroot/www.1.com;
       rewrite_log on;
       if ( $request_uri ~ "\.htpasswd|\.bak" )
       {
             return 404;
              rewrite /(.*) /aaa.txt;  #该行配置不会被执行。 
       }
     }

[root@k8s-node01 vhost]# curl -x127.0.0.1:80 www.1.com/.htppasswd
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
#//返回字符串
server{
    listen 80;
    server_name www.lsy.com;
    return 200 "hello";
}
#//如果要想返回字符串,必须要加上状态码,否则会报错。
#//还可以支持json数据

location ^~ /lsy{
    default_type application/json ;
    return 200  '{"name":"lsy","id":"100"}';
}

#//也支持写一个变量

location /test {
    return 200 "$host $request_uri";
}
#//返回url
server{
    listen 80;
    server_name www.lsy.com;
    return http://www.lsylinux.com/123.html;
    rewrite /(.*) /abc/$1;  //该行配置不会被执行。
}

rewrite具体规则

格式:rewrite regex replacement [flag]

* rewrite配置可以在server、location以及if配置段内生效

* regex是用于匹配URI的正则表达式,其不会匹配到$host(域名)

* replacement是目标跳转的URI,可以以http://或者https://开头,也可以省略掉$host,直接写$request_uri部分(即请求的链接) * flag,用来设置rewrite对URI的处理行为,其中有break、last、rediect、permanent, rediect和permanent的区别在于,前者为临时重定向(302),而后者是永久重定向(301),对于用户通过浏览器访问,这两者的效果是一致的。 但是,对于搜索引擎蜘蛛爬虫来说就有区别了,使用301更有利于SEO。所以,建议replacemnet是以http://或者https://开头的flag使用permanent。

location / {
    rewrite /(.*) http://www.lsy.com/$1 permanent;
}
#说明:.*为正则表达式,用()括起来,在后面的URI中可以调用它,第一次出现的()用$1调用,
#第二次出现的()用$2调用,以此类推。
location / {
    rewrite /.* http://www.lsy.com$request_uri permanent;
}
#在replacement中,支持变量,这里的$request_uri就是客户端请求的链接
server{
    listen 80;
    server_name www.123.com;
    root /tmp/123.com;
    index index.html;
    rewrite /(.*) /abc/$1 redirect;
}
#本例中的rewrite规则有问题,会造连续循环,最终会失败,解决该问题有两个方案。
#关于循环次数,经测试发现,curl 会循环50次,chrome会循环80次,IE会循环120次,firefox会循环20次。

#测试
[root@k8s-node01 vhost]# vi www.2.com.conf 
server {

       listen 80;
       server_name www.2.com;
       root /data/wwwroot/www.2.com;
      location /
      {

         rewrite /(.*) /abc/$1 redirect;
       }
       }
                 
[root@k8s-node01 vhost]# curl -x127.0.0.1:80 www.2.com
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>
[root@k8s-node01 vhost]# curl -x127.0.0.1:80 www.2.com -L
curl: (47) Maximum (50) redirects followed
[root@k8s-node01 vhost]# curl -x127.0.0.1:80 www.2.com -I
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.14.0
Date: Tue, 27 Aug 2019 15:11:36 GMT
Content-Type: text/html
Content-Length: 161
Location: http://www.2.com/abc/
Connection: keep-alive

[root@k8s-node01 vhost]# curl -x127.0.0.1:80 www.2.com/abc -I
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.14.0
Date: Tue, 27 Aug 2019 15:12:01 GMT
Content-Type: text/html
Content-Length: 161
Location: http://www.2.com/abc/abc
Connection: keep-alive

#解决
server{
    listen 80;
    server_name www.123.com;
    root /tmp/123.com;
    index index.html;
    rewrite /(.*) /abc/$1 break;
}
#在rewrite中使用break,会避免循环。
server{
    listen 80;
    server_name www.123.com;
    root /tmp/123.com;
    index index.html;
    if ($request_uri !~ '^/abc/')
    {
        rewrite /(.*) /abc/$1 redirect;
    }
}
#加一个条件限制,也可以避免产生循环

rewrite常用举例

域名跳转

# 不带条件的
server{
    listen 80;
    server_name www.lsylinux.com;
    rewrite /(.*) http://www.lsy.com/$1 permanent;
    .......
    
}

#带条件的
server{
    listen 80;
    server_name www.lsylinux.com aminglinux.com;
    if ($host != 'www.lsylinux.com')
    {
        rewrite /(.*) http://www.lsylinux.com/$1 permanent;
    }
    .......
    
}
#http跳转到https
server{
    listen 80;
    server_name www.lsylinux.com;
    rewrite /(.*) https://www.aminglinux.com/$1 permanent;
    .......
    
}
#域名访问二级目录
server{
    listen 80;
    server_name bbs.lsylinux.com;
    rewrite /(.*) http://www.lsylinux.com/bbs/$1 last;
    .......
    
}
#静态请求分离
server{
    listen 80;
    server_name www.lsylinux.com;
    location ~* ^.+.(jpg|jpeg|gif|css|png|js)$ 
    {
        rewrite /(.*) http://img.lsylinux.com/$1 permanent;
    }

    .......
    
}
#或者
server{
    listen 80;
    server_name www.lsylinux.com;
    if ( $uri ~* 'jpg|jpeg|gif|css|png|js$')
    {
        rewrite /(.*) http://img.lsylinux.com/$1 permanent;
    }

    .......
    
}

防盗链


server{
    listen 80;
    server_name www.lsylinux.com;
    location ~* ^.+.(jpg|jpeg|gif|css|png|js|rar|zip|flv)$
    {
        valid_referers none blocked server_names *.lsylinux.com lsylinux.com *.lsy.com lsy.com;
        if ($invalid_referer)
        {
            rewrite /(.*) http://img.lsylinux.com/images/forbidden.png;
        }
    }

    .......
    
}

# *这里是通配,跟正则里面的*不是一个意思,none指的是referer不存在的情况(curl -e 测试),
# blocked指的是referer头部的值被防火墙或者代理服务器删除或者伪装的情况,
# 该情况下,referer头部的值不以http://或者https://开头(curl -e 后面跟的referer不以http://或者# https://开头)。
# 或者
    location ~* ^.+.(jpg|jpeg|gif|css|png|js|rar|zip|flv)$
    {
        valid_referers none blocked server_names *.lsylinux.com *.lsy.com lsylinux.com lsy.com;
        if ($invalid_referer)
        {
            return 403;
        }
    }

伪静态


location /  {
    rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last;
    rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last;
    rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last;
    rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last;
    rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last;
    rewrite ^([^\.]*)/(fid|tid)-([0-9]+)\.html$ $1/index.php?action=$2&value=$3 last;
}

rewrite多个条件的并且

#//nginx里面if不能嵌套
server {

       listen 80;
       server_name www.1.com;
       root /data/wwwroot/www.1.com;
       rewrite_log on;

       set $tmp 0;
       if ( $request_uri !~ "^/abc/" )
       {
         set $tmp "${tmp}1";
       }

       if ( $http_user_agent ~ 'IE|chrome' )
       {
         set $tmp "${tmp}2";
       }
       if ( $tmp = "012" )
       {
         return 406;
       }}


#// -A 模拟浏览器
[root@k8s-node01 vhost]# /usr/local/nginx/sbin/nginx -s reload
[root@k8s-node01 vhost]# curl -x127.0.0.1:80 -A "dlkfakfchromefjoe" www.1.com/1.html
<html>
<head><title>406 Not Acceptable</title></head>
<body bgcolor="white">
<center><h1>406 Not Acceptable</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>


[root@k8s-node01 vhost]# curl -x127.0.0.1:80 -A "dlkfakfchromefjoe" www.1.com/abc/1.html
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>


[root@k8s-node01 vhost]# curl -x127.0.0.1:80 -A "dlkfakfchrddomefjoe" www.1.com/abc/1.html
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.14.0</center>
</body>
</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值