• Web架构之Nginx重定向Rewrite


    1、Rewrite 简介

    和Apache等Web服务软件一样,Nginx Rewrite的主要功能是实现URL的地址重写,以及重定向Nginx的Rewrite规则需要PCRE软件的支持,通过Perl兼容正则表达式语法进行规则的匹配

    Rewrite使用场景:
    1.URL访问跳转:支持开发设计,页面跳转,兼容性支持,展示效果
    2.SER优化:依赖于url路径,以便支持搜索引擎录入
    3.维护:后台维护,流量转发等
    4.安全:伪静态,真是动态页面进行伪装

    Rewrite 语法

    Syntax:rewrite regex replacement {flag};
    default:none
    Context:server、location、if
    
    // 所有的请求转发至/pages/maintain.html
    rewrite ^(.*)$ /pages/maintain.html break;
    

    正则表达式:

    表达式 说明
    . 匹配除换行符以外的任意字符
    ? 重复0次或1次
    + 重复1次或更多次
    * 匹配所有
    d 匹配数字
    ^ 匹配字符串的开始
    $ 匹配字符串的结尾
    {n} 重复n次
    {n,} 重复n次或更多次
    [c] 匹配单个字符c
    [a-z] 匹配a-z小写字母的任意一个

    正则表达式中特殊字符

    //  转义字符
    rewrite index.php$ /pages/maintain.html break;
    
    // ()用于匹配括号之间的内容, 通过$1,$2调用 
    if ($http_user_agent ~ Chrome){
          rewrite ^(.*)$ /chrome/$1 break;
      }
    

    正则表达式终端测试工具

    $ yum install -y pcre-tools
    $ pcretest
    PCRE version 8.32 2012-11-30
    
    re> /(d+).(d+).(d+).(d+)/
    data> 10.0.0.7
     0: 10.0.0.7
     1: 10
     2: 0
     3: 0
     4: 7
    

    Rewrite标记Flag:

    flag 说明
    last 停止rewrite检测
    break 停止rewrite检测
    redirect 返回302临时重定向,地址栏会显示跳转后的地址
    permanent 返回301永久重定向,地址栏会显示跳转后的地址

    对比flag中break和last:

    $ vim /etc/nginx/conf.d/rewrite.conf 
    server {
        listen 80; 
        server_name localhost; 
        root /soft/code; 
           
        location ~ ^/break {
              rewrite ^/break /test break; 
            }
              
        location ~ ^/last {
              rewrite ^/last /test last;
            }
    
        location /test {
              default_type application/json; 
    				  return 200 '{"status":"success"}';
            } 
    }
    

    测试break

    $ curl 127.0.0.1/break/xx.html
    <html>
    <head><title>301 Moved Permanently</title></head>
    <body>
    <center><h1>301 Moved Permanently</h1></center>
    <hr><center>nginx/1.16.1</center>
    </body>
    </html>
    

    测试last

    $ curl 127.0.0.1/last
    {"status":"success"}
    

    last 与 break 对比总结:
    1.last:会新建立一个请求, 所以会重新进行匹配
    2.break:跳出rewrite阶段,不会在匹配。

    对比flag中redirect和permanent:

    [root@lb01 /]# cat /application/nginx/conf/extra/rewrite.conf 
    server {
          listen 80;
          server_name localhost;
          root /soft/code;
          location ~ ^/jason {
              rewrite ^/jason http://www.baidu.com redirect; # 临时重定向
            # rewrite ^/jason http:// www.baidu.com permanent; # 永久重定向
                    }
    }
    

    2、Rewrite 应用场景

    可以调整用户浏览的URL
    为了让搜索引擎收录网站内容及用户体验更好
    网站换新域名后,让旧的域名的访问跳转到新的域名上

    2.1、基于uri做rewrite

    正常访问: 127.0.0.1/course-11-22-33.html
    改写后: 127.0.0.1/course/11/22/course_33.html

    1.环境准备

    $ mkdir /soft/code/course/11/22/ -p
    $ echo "<h1>Nginx</h1>"  > /soft/code/course/11/22/course_33.html
    

    2.修改nginx配置文件

    $ vim  /etc/nginx/conf.d/rewrite.conf
    server {
         listen 80;
         root /soft/code;
         index index.html;
    
         location / {
             rewrite_log on;
             error_log /var/log/nginx/rewrite.log notice;
             rewrite ^/course-(d+)-(d+)-(d+).html /course/$1/$2/course_$3.html break;
            }
    }
    

    3.测试结果

    $ curl  127.0.0.1/course-11-22-33.html
    <h1>Nginx</h1>
    
    // 截一段rewrite日志
    2020/03/14 14:21:24 [notice] 2432#2432: *53 rewritten data: "/course/11/22/course_33.html", args: "", client: 127.0.0.1, server: , request: "GET /course-11-22-33.html HTTP/1.1", host: "127.0.0.1"
    

    2.2、基于http请求头做rewrite

    可以根据http请求头的变量来匹配做rewrite

    if ($http_user_agent ~* "Chrome") {
           rewrite ^/nginx http://www.baidu.com/index.html redirect;
                    }
    

    别名和Rewrite的区别:
    1)用别名效率高,但是看不到改过的域名
    2)用Rewrite 301跳转的话,能看到新的域名,但是需要再次发送HTTP请求

    3、Rewrite 案例

    3.1、案例一

    输入:127.0.0.1/jason-2018-11-15_book/index.html
    跳转:127.0.0.1/jason/2018/11/15_book/index.html

    1.环境准备

    $ mkdir /soft/code/jason/2018/11/15_book/ -p
    $ echo "book" > /soft/code/jason/2018/11/15_book/index.html
    

    2.修改nginx配置文件

    $ cat /etc/nginx/conf.d/rewrite.conf
    server {
         listen 80;
         root /soft/code;
         index index.html;
    
         location / {
            index index.html;
            rewrite_log on;
            error_log /var/log/nginx/rewrite.log notice;
            rewrite ^/jason-(d+)-(d+)-(d+)_book/index.html /jason/$1/$2/$3_book/index.html break;
        }
    }
    

    3.测试结果

    $ curl 127.0.0.1/jason-2018-11-15_book/index.html
    book
    
    // 截一段rewrite日志
    2020/03/14 14:29:01 [notice] 3371#3371: *58 "^/jason-(d+)-(d+)-(d+)_book/index.html" matches "/jason-2018-11-15_book/index.html", client: 127.0.0.1, server: , request: "GET /jason-2018-11-15_book/index.html HTTP/1.1", host: "127.0.0.1"
    2020/03/14 14:29:01 [notice] 3371#3371: *58 rewritten data: "/jason/2018/11/15_book/index.html", args: "", client: 127.0.0.1, server: , request: "GET /jason-2018-11-15_book/index.html HTTP/1.1", host: "127.0.0.1"
    

    3.2、案例二

    输入:127.0.0.1/jason-2018-12-29_word/xxx.html
    跳转:127.0.0.1/jason/2018/12/29_word/xxx.html

    1.环境准备

    $ mkdir /soft/code/jason/2018/12/29_word/ -p
    $ echo "word1" > /soft/code/jason/2018/12/29_word/1.html
    $ echo "word2" > /soft/code/jason/2018/12/29_word/2.html
    $ echo "word3" > /soft/code/jason/2018/12/29_word/3.html
    

    2.修改nginx配置文件

    $ cat /etc/nginx/conf.d/rewrite.conf
    server {
         listen 80;
         root /soft/code;
         index index.html;
    
         location / {
            index index.html;
            rewrite_log on;
            error_log /var/log/nginx/rewrite.log notice;
            rewrite ^/jason-(d+)-(d+)-(d+)_word/(.*)$  /jason/$1/$2/$3_word/$4 break;
        }
    }
    

    3.测试结果

    $ curl 127.0.0.1/jason-2018-12-29_word/1.html
    word1
    $ curl 127.0.0.1/jason-2018-12-29_word/2.html
    word2
    $ curl 127.0.0.1/jason-2018-12-29_word/3.html
    word3
    
    // 截一段rewrite日志
    2020/03/14 14:32:14 [notice] 3385#3385: *65 "^/jason-(d+)-(d+)-(d+)_word/(.*)$" matches "/jason-2018-12-29_word/1.html", client: 127.0.0.1, server: , request: "GET /jason-2018-12-29_word/1.html HTTP/1.1", host: "127.0.0.1"
    2020/03/14 14:32:14 [notice] 3385#3385: *65 rewritten data: "/jason/2018/12/29_word/1.html", args: "", client: 127.0.0.1, server: , request: "GET /jason-2018-12-29_word/1.html HTTP/1.1", host: "127.0.0.1"
    2020/03/14 14:32:15 [notice] 3385#3385: *66 "^/jason-(d+)-(d+)-(d+)_word/(.*)$" matches "/jason-2018-12-29_word/2.html", client: 127.0.0.1, server: , request: "GET /jason-2018-12-29_word/2.html HTTP/1.1", host: "127.0.0.1"
    2020/03/14 14:32:15 [notice] 3385#3385: *66 rewritten data: "/jason/2018/12/29_word/2.html", args: "", client: 127.0.0.1, server: , request: "GET /jason-2018-12-29_word/2.html HTTP/1.1", host: "127.0.0.1"
    2020/03/14 14:32:16 [notice] 3385#3385: *67 "^/jason-(d+)-(d+)-(d+)_word/(.*)$" matches "/jason-2018-12-29_word/3.html", client: 127.0.0.1, server: , request: "GET /jason-2018-12-29_word/3.html HTTP/1.1", host: "127.0.0.1"
    2020/03/14 14:32:16 [notice] 3385#3385: *67 rewritten data: "/jason/2018/12/29_word/3.html", args: "", client: 127.0.0.1, server: , request: "GET /jason-2018-12-29_word/3.html HTTP/1.1", host: "127.0.0.1"
    

    4、Rewrite额外补充

    Rewrite 匹配优先级:
    1.执行server块的rewrite指令
    2.执行location匹配
    3.执行选定的location中的rewrite

    Rewrite 优雅书写:

    server { 
    	listen 80; 
    	server_name www.bgx.com bgx.com; 
    	if ($http_host = nginx.org){ 
    	rewrite (.*) http://www.bgx.com$1; 
    		} 
    }
    
    # 改良版 
    server {
    	listen 80;
    	server_name bgx.com;
    	rewrite ^ http://www.bgx.com$request_uri?; 
    }
    
    	server { 
    	listen 80;
    	 server_name www.bgx.com; 
    }
    
  • 相关阅读:
    ArcMap导出图层属性为excel表
    ArcMap面转为线
    vue(18)声明周期函数
    geoserver发布mbtiles文件
    docker部署geoserver
    vue(17)组件插槽slot的使用
    vue(16)父子组件之间直接相互访问
    MySQL常用查询语句积累
    数据库的基本设计
    HashMap学习
  • 原文地址:https://www.cnblogs.com/jasonminghao/p/12492073.html
Copyright © 2020-2023  润新知