Nginx rewrite深入解读

Nginx rewrite深入解读

1.什么是rewrite

官方解读:nginx的重写模块(rewrite)是一个简单的正则表达式匹配与一个虚拟堆叠机结合。
个人解读:nginx的rewrite是结合正则表达式和标志位实现url重写、改变以及重定向。如:域名跳转,防盗链,反向代理,各种跳转(跳转维护界面,前端跳转,基于uri跳转,基于目录跳转等)


2.rewrite的支撑源头

nginx通过ngx_http_rewrite_module模块支持url重写、支持if条件判断。依赖于PCRE库,因此需要安装pcre。


3.rewrite的7个指令

3.1.break

  • 语法:break
  • 默认值:none
  • 配置段:server,location,if
  • 作用:完成当前设置的重写规则,停止处理后续rewrite指令集,并不在重新查找,但是当前location内剩余非rewrite语句和location外的的非rewrite语句可以执行。
  • 实例:
if ($slow) {
    limit_rate 10k;
    break;
}

3.2.if

  • 语法:if(condition){…}
  • 默认值:none
  • 配置段:server,location
  • 作用:对给定的条件condition进行判断
  • conditon:if条件(conditon)可以是如下任何内容:
    1. 一个变量名:空字符传“ ”或者一些“0”开始的字符串为false
    2. 字符串比较:使用=或!=运算符
    3. 正则表达式匹配:用~或~*+正则表达式匹配的变量,如果这个正则表达式中包含}或;,则整个表达式需要用” 或’ 包围
    4. 文件是否存在:使用-f或者!-f操作符
    5. 目录是否存在:使用-d或者!-d操作符
    6. 文件、目录、符号链接是否存在:使用-e或者!-e操作符
    7. 文件是否可执行:使用-x或者!-x操作符
  • 实例:
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
}
if ($http_user_agent ~ MSIE) {    
    rewrite ^(.*)$ /msie/$1 
    break;
}

3.3.return

  • 语法:
    • return code;
    • return url;
    • return code url;
  • 默认值:none
  • 配置段:server,location,if
  • 作用:
    1. 停止处理,并为客户端返回状态码。
    2. 非标准的444状态码将关闭连接,不发送任何响应头
    3. 可以使用的状态码有:204/400/402-406/408/410/411/413/416/500-504
    4. 如果状态码后面是一个url,该url将成为location头的补值。
    5. 没有状态码的url将被视为一个默认的302状态码
    6. 状态码附带文字段落,该文本将被放置在响应主体里
  • 实例:
if ($request_method = POST) {
     return 405;
}
if ($invalid_referer) {
     return 403;
}

3.4.rewrite

  • 语法:rewrite regex replacement [flag];
  • 默认值:none
  • 配置段:server,location,if
  • 作用:
    1. 如果一个URI匹配指定的正则表达式regex,URI就按照replacement重写
    2. 可以在重写指令后添加标识【flag】
    3. flag标志可以停止继续处理
    4. 如果replacement以”http://”或”https://”开始,将不再继续处理rewrite指令,这个重定向将返回给客户端
  • flag标识符可为以下值:
    1. last:停止处理后续rewrite指令集,然后对当前重写的新URI在rewrite指令集上重新查找。
    2. break:完成rewrite指令,并不在重新查找,但是当前location内剩余非rewrite语句和location外的的非rewrite语句可以执行。
    3. redirect:如果replacement不是以http:// 或https://开始,返回302临时重定向
    4. permannet:返回301永久重定向
  • 最终完整的重定向URL包括请求scheme(http://,https://等),请求的server_name_in_redirect和 port_in_redirec三部分 ,说白了也就是http协议 域名 端口三部分组成。
  • 实例:
location /download/ {     
    rewrite ^(/download/.*)/media/(.*)..*$ $1/mp3/$2.mp3 break;     
    rewrite ^(/download/.*)/audio/(.*)..*$ $1/mp3/$2.ra break;     
    return 403;
} 

3.5.rewrite_log

  • 语法:rewrite_log on|off;
  • 默认值:rewrite_log off;
  • 配置段:http,server,location,if
  • 作用:启用时将在error log中记录notice级别的重写日志
  • 实例:
rewrite_log on;
error_log logs/xxx.error.log notice;

3.6.set

  • 语法:set variable value;
  • 默认值:none
  • 配置段:server,location,if
  • 作用:定义一个变量并赋值,值可以是文本,变量或者文本变量混合体。

3.7.uninitialized_variable_warn

  • 语法:uninitialized_variable_warn on | off;
  • 默认值:uninitialized_variable_warn on
  • 作用域:http,server,location,if

- 作用:控制是否记录未初始化的警告信息


4.rewrite的规则

4.1.rewrite指令执行顺序

  1. 执行server块的rewrite指令(这里的块指的是server关键字后{}包围的区域,其它xx块类似)
  2. 执行location匹配
  3. 执行选定的location中的rewrite指令
  4. 如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件
    如果循环超过10次,则返回500 Internal Server Error错误

4.2.正则表达式-引用取值

  • 可以使用括号来捕获,后续可用位置来将其引用,位置变量取决于捕获正则表达式中的顺序, 1 2则引用第二个括号中的值
  • 实例:
^/img/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|gif|jpg)$

1) 1:([az]2)2 2:是([a-z0-9]{5}),由小写字母或0-9组成的5个字符串
3) 3:(.)4 4:是(png|gif|jpg),其中一个

4.3.return返回规则

  1. 停止处理,并为客户端返回状态码。
  2. 非标准的444状态码将关闭连接,不发送任何响应头
  3. 可以使用的状态码有:204/400/402-406/408/410/411/413/416/500-504
  4. 如果状态码后面是一个url,该url将成为location头的补值。
  5. 没有状态码的url将被视为一个默认的302状态码
  6. 状态码附带文字段落,该文本将被放置在响应主体里
location = /img404.html{
    return 404 "image not found\n"; 
}

5.rewrite小实例

5.1.禁止.sh .bash

location ~ .*\.(sh|bash)?${  
  return 403;  
} 


5.2.目录跳转

location /a{
         alias /data/site/b.chen.com/a;
         rewrite ^/a/?$ /b last;
}
location /b{
        alias /data/site/b.chen.com/b;
        default_type 'text/html';
        echo "url is a -> rewrite to b...";
}


5.3.防盗链实例

5.3.0.valid_referer指令说明

Nginx配置中有一个指令valid_referers,用来获取Referer头域中的值,并且根据该值的情况给Nginx全局变量 invalidrefererReferervalidreferers invalid_referer变量将会被赋值为1。
valid_referer指令的语法结构为:

valid_referers none | blocked | server_names | string ....;
none 检测Referer头域不存在的请求
blocked 检测Referer头域的值被防火墙或者代理服务器删除或伪装的情况。
这种情况下,该头域的值不以“http://”或者“https://”开头
server_names 设置一个或多个URL,检测Referer头域的值是否是这些URL中的某个。
从nginx 0.5.33以后支持使用通配符“*”。
5.3.1.nginx.conf的server配置
server{
    server_name echo.chen.com;
    listen 80;
    location /{
        root /data/site/echo.chen.com;
        index index.html;
    }
    location ~ .*\.(jpg|png)$ {
        valid_referers none blocked echo.chen.com;
        if ($invalid_referer) {
                return 412;
                break;
        }
       root /data/site/echo.chen.com;
    }
    location =/error.html{
            root /data/site/echo.chen.com;
    }
}
  • /data/site/echo.chen.com 自行创建目录
  • index.html内容如下:
this is index.html
<img src="http://echo.chen.com/1.jpg">
5.3.2.Windows下host配置
192.168.1.111 b.chen.com
192.168.1.111 echo.chen.com
  • 配置不同域名指定同一个ip,以便测试
5.3.3.浏览器测试

访问指定的域名,即可访问到图片

使用b.chen.com进行访问则不能访问到服务器图片


5.4.域名跳转

server{
    server_name jump.chen.com;
    listen 80;
    access_log off;
    location /{
            default_type "text/html";
            echo "it is echo.chen.com jump to jump.chen.com";
    }
}
server{
    server_name echo.chen.com;
    listen 80;
    rewrite ^/ http://jump.chen.com/;
    location /{
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值