美文网首页
nginx 的 rewrite

nginx 的 rewrite

作者: OOM_Killer | 来源:发表于2019-05-17 00:02 被阅读0次

    其实nginx的rewrite模块是在日常nginx配置中十分常用的模块,应该是除了 real_ip 模块、匹配时用到的find_config模块和前端资源配置的 static 模块外的最常用的了吧。

    Nginx的处理顺序
    nginx的处理顺序是11 个模块,处在realip模块后的就是 rewrite 模块了。而rewrite的模块中的return一旦执行就不会再处理接下来的模块了。而rewrite 分两部分。在 postread阶段,rewrite -> find_config -> rewrite 这样去执行的。

    Rewrite 模块

    return 指令

    rewrite 模块提供了一个指令 return 。
    return 的语法可以是

    return code [text];
    return code URL;
    return URL;
    

    而再返回状态码上。

    • Nginx自定义
      • 444 关闭连接 (客户端是收不到这样的返回码)
    • HTTP 1.0 标准
      • 301 http1.0 永久重定向 (会将 post方法变成 get)
      • 302 临时重定向,禁止被缓存 (会将post方法变成 get)
    • HTTP 1.0 标准
      • 303 临时重定向,允许改变方法,禁止被缓存
      • 307 临时重定向,不允许改变方法,禁止被缓存
      • 308 永久重定向,不允许改变方法。
    error_page 指令

    error_page 指令是在发现错误返回码的时候重新定义返回的页面.
    这里需要知道 return 指令会先于 error_page 执行。如果return指令被执行到了,其他的指令都将无法被执行。

    1. error_page 404 /404.html;
    2. error_page 500 502 503 504 /50x.html;
    3. error_page 404 =200 /empty.gif;  (返回码重新置为200)
    4. error_page 404 = /404.php;
    5. location / {
             error_page 404 = @fallback;
    }
        location @fallback {
              proxy_pass http://backend;
    }
    6. error_page 403 http://example.com/forbidden.html;
    7. error_page 404 =301 http://example.com/notfound.html;
    
    rewrite 指令

    rewrite 的语法是这样的,可以通过 rewrite_log on; 记录rewrite。

    rewrite regex replacement [flag];
    
    • 将regex指定的url替换成 replacement 这个新的url。
    • 当replacement以 http:// 或者 $schema 开头,直接会返回302重定向。
    • 替换后的url根据flag指定的方式进行处理。
      • last:用replacement这个url 重新进行location匹配。
      • break:break指令停止当前脚本的执行,不再匹配。
      • redirect:返回302重定向。
      • permanent:返回301重定向。

    具体的例子来访问一下。
    目录的结构为

    file
    ├── first
    │   └── 1.txt    # 1
    ├── second
    │   └── 2.txt    # 2
    └── third
        └── 3.txt    # 3
    

    如下的配置

            root html/file/;
            location /first {
                    rewrite /first(.*) /second$1 last;
                    return 200 'first';
            }
            location /second {
                    rewrite /second(.*) /third$1 break;
                    return 200 'second';
            }
            location /third {
                    return 200 'third';
            }
    
    

    这里再重申一次,last表示匹配上后再匹配,break是中止往下执行,如果第二个没加 break的话,会 return 200 的。

    curl -H"Host:rewrite.example.wjx" http://127.0.0.1/first/3.txt
    3
    curl -H"Host:rewrite.example.wjx" http://127.0.0.1/second/3.txt
    3
    curl -H"Host:rewrite.example.wjx" http://127.0.0.1/third/3.txt
    third
    

    如果不要 last ,不要 break会怎么样呢,他们的作用就是中止下面的return等指令运行
    而last是rewrite后的url还可以再作rewrite,break就直接rewrite,不再做新的rewrite了

    curl -H"Host:rewrite.example.wjx" http://127.0.0.1/first/3.txt
    first
    curl -H"Host:rewrite.example.wjx" http://127.0.0.1/second/3.txt
    second
    curl -H"Host:rewrite.example.wjx" http://127.0.0.1/third/3.txt
    third
    

    最后就是 permanent 和 redirect了。其实这两就是301 和 302 ,且如果 replacement 中有协议的话,默认就是 302
    如下配置

            location /redirect1 {
                    rewrite /redirect1(.*) $1 permanent;
            }
            location /redirect2 {
                    rewrite /redirect2(.*) $1 redirect;
            }
            location /redirect3 {
                    rewrite /redirect3(.*) http://rewrite.example.wjx$1;
            }
            location /redirect4 {
                    rewrite /redirect4(.*) http://rewrite.example.wjx$1 permanent;
            }
    

    访问后如下,第一个会返回301,第二,三个会返回302,第四个返回301。

    if 指令

    if 指令也是rewrite模块中的一个指令。
    其可作用于 server 和 location 块中。
    一般可使用 字符串与变量做匹配 '=' 和 '!=' 。
    也可以正则匹配 '~' 或 '~!'。
    检测文件是否存在'-f' 或 '!-f' ,目录则是 '-d'。
    检查文件,目录,软链接是否存在' -e' 或者 '!-e'。
    检查是否为可执行文件,使用'-x' 或者 '!-x'。
    以下为示例。

    if ($http_user_agent ~ MSIE) {
        rewrite ^(.*)$ /msie/$1 break;
    }
    if ($http_cookie ~* "id=([^;]+(?:;|$))") {
        set $id $1;
    }
    if ($request_method = POST) {
        return 405;
    }
    if ($slow) {
        limit_rate 10k;
    }
    if ($invalid_referer) {
        return 403;
    }
    

    相关文章

      网友评论

          本文标题:nginx 的 rewrite

          本文链接:https://www.haomeiwen.com/subject/yrcgaqtx.html