当前位置: 首页 > news >正文

nginx http rewrite module 详解

大家好,我是 17。

今天和大家聊聊 nginx http rewrite module 。

简单来说, ngx_http_rewrite_module module 用正则匹配请求,改写请求,然后做跳转。可以是内部跳转,也可以是外部跳转。

学习这个模块的时候,把 rewrite_log 打开,可以在 error log 里查看跳转信息

 rewrite_log on; error_log /home/log/test-error.log notice;

注意 notice 是必须的

顺序执行和循环跳转

  1. 直接写在 server level 的 指令,顺序执行。
  2. 写在 location 中的指定顺序执行。可以跳到其它 location ,最多不超过 10次。
server{rewrite ^/users/(.*)$ /show?user=$1 ;rewrite ^/teachers/(.*)$ /show?teacher=$1 ;
}

请求 /users/1 ,先执行第一条 rewrite ^/users/(.*)$ /show?user=$1
再执行第二条 rewrite ^/teachers/(.*)$ /show?teacher=$1 ; 虽然第一条匹配到了,还是会执行第二条。这就是顺序执行的意思。

location /{rewrite ^/teachers/(.*)$ /show/$1;rewrite ^/users/(.*) /show/$1;
}
location /show/{rewrite ^/show/(.*)$ /users/$1 ;
}

请求 /users/1,命中第一个location 。顺序执行第一个 rewrite,没命中,即使命中也会继续执行第二 rewrite ,命中。执行 rewirte 指令跳转到第二个location /show/,执行 rewirte 又回跳回 / ,这样循环10次,报 500 错误,查看 error 日志可以看到说明。

rewrite or internal redirection cycle while processing "/show/1"

这个过程演示了 location 中 rewrite 的执行逻辑。顺序执行,循环跳转。

rewrite module 中还有 5 个指令 break, if, return, rewrite, and set。

return

return 可以直接返回,打断后面的 rewrite module 指令的执行。

location / {return 409;rewrite ^/teachers/(.*)$ /show/$1;
}

执行 return 后,后面的指令就没有机会执行了。

return code [text];
return code URL;
return URL;
location /admin/{return 403 '没有访问权限';
}
location / {return 302 $scheme://www.baidu.com$request_uri;
}location /abc/{return 404;
}

set,break 比较简单,和其它语言差不多。下面着重讲下 rewirte 指令的 flag。

rewrite 指令的 flag

rewrite regex replacement [flag]

flag有四种

  • last 停止执行后面的 ngx_http_rewrite_module 指令,并发起新的 location 匹配。
  • break 停止执行后面的 ngx_http_rewrite_module 指令,然后没有后续了,不再发起 location 匹配。
  • redirect 执行 302跳转,后面的指令不再执行。
  • permanent 执行 301跳转,后面的指令不再执行。

last、break 停止执行的是 ngx_http_rewrite_module 指令,其它指令不受影响,还是会执行的。

regex 匹配的是路径部分

location / {rewrite ^/teacher/(.*)$ /show1/$1 last;rewrite ^/teacher/(.*) /show2/$1;
}
location /show1{return 900;
}
location /show2{return 901;
}curl http://localhost:3000/teacher/1
HTTP/1.1 900因为 last 会终止后面的  ngx_http_rewrite_module 指令,所以 第二句 rewrite ^/teacher/(.*) /show2/$1 不会执行。第一句执行完后,跳到 /show1,返回 900如果把 last 换成  break
HTTP/1.1 404因为 break 不再执行跳转,直接查找 show1/1 找不到,报 404.把 last 换成 redirect.
HTTP/1.1 302 浏览器会请求两次。把 last 换成 permanent.
HTTP/1.1 301 浏览器会请求两次。

如果 replacement 是 http开头,是可以直接跳转的

location / {rewrite ^/teacher/ http://juejin.cn
}curl http://localhost:3000/teacher/1
HTTP/1.1 302 
Location: http://juejin.cn相当于 redirect 指令的效果。

if 语句

if 语句不复杂,但是非常有用,可以这样说,用 if 可以实现很多指令,但是用内置指令更简洁,还是要优先用指令。

if ($param) 如果 $param 为空字符串或 0 为假,其它情况为真。

注意 if 后面必须要有空格,否则报错。

set $param '0';
set $param 0;
set $param '';这三种写法 $param 都为假,其它情况都为真

用 = ,!=判断相等。

 if ($request_method = POST){return 403;}

注意 是一个 = 不是两个=, 等号左右必须要有空格,否则报错

用正则表达式判断

~ 区分大小写
if ($http_user_agent ~ mobile)~* 不区分大小写
if ($http_referer ~* juejin\.cn)!~ 和 !~* 是对应的两个否定写法,不再举例了。

用 flag

-f !-f  文件是否存在
if (-f $request_filename)
if (!-f $request_filename)-d !-d 目录是否存在
-e !-e 文件或目录是否存在
-x !-e 是否可执行## url 美化
http rewrite 一个应用就是 url 美化。
我们在开发的时候用的 url 是这样的 

/users?id=1

让别人访问的时候可能是这样的

/users/1

所以我们需要把 `/users/1` 转为 `/users?id=1` ,这时就需要 rewrite 出场了。

location /users/{
rewrite ^/users/(.*)$ /nodejs/id=$1? last;
}
location /nodejs/{
proxy_pass http://127.0.0.1:3000;
}

当请求`/users/1` 的时候,命中 location /users/ ,执行rewrite 指令, last flag 指示停止后面的rewrite 指令并做内部跳转,匹配到 location /nodejs/ ,经过 proxy_pass 指令,转到 /nodejs/ 。
http://www.lryc.cn/news/21150.html

相关文章:

  • 机器学习可解释性一(LIME)
  • CV学习笔记-MobileNet
  • C++进阶——继承
  • 数据结构---单链表
  • redis数据结构的底层实现
  • 【JavaSE】复习(进阶)
  • Java 主流日志工具库
  • 产品经理有必要考个 PMP吗?(含PMP资料)
  • 什么是原型、原型链?原型和原型链的作用
  • 条件期望4
  • 网络协议分析(2)判断两个ip数据包是不是同一个数据包分片
  • 6.2 负反馈放大电路的四种基本组态
  • MySQL进阶之锁
  • 【Mac 教程系列】如何在 Mac 上破解带有密码的 ZIP 压缩文件 ?
  • 【Acwing 周赛复盘】第92场周赛复盘(2023.2.25)
  • L1-087 机工士姆斯塔迪奥
  • 本周大新闻|索尼PS VR2立项近7年;传腾讯将引进Quest 2
  • aws console 使用fargate部署aws服务快速跳转前端搜索栏
  • Redis实战之Redisson使用技巧详解
  • SQLAlchemy
  • 【Linux学习笔记】8.Linux yum 命令和apt 命令
  • windows服务器实用(4)——使用IIS部署网站
  • Random(二)什么是伪共享?@sun.misc.Contended注解
  • Linux解压压缩
  • JavaSe第3次笔记
  • 非人工智能专业怎样从零开始学人工智能?
  • MyBatis之增、删、查、改
  • 死磕Spring,什么是SPI机制,对SpringBoot自动装配有什么帮助
  • 因果推断10--一种大规模预算约束因果森林算法(LBCF)
  • Linux基础命令-df显示磁盘的使用情况