大家好,我是 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 是必须的
顺序执行和循环跳转
- 直接写在 server level 的 指令,顺序执行。
- 写在 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文章来源:https://www.toymoban.com/news/detail-402653.html
所以我们需要把 `/users/1` 转为 `/users?id=1` ,这时就需要 rewrite 出场了。
location /users/{
rewrite ^/users/(.*)$ /nodejs/id=$1? last;
}
location /nodejs/{
proxy_pass http://127.0.0.1:3000;
}文章来源地址https://www.toymoban.com/news/detail-402653.html
当请求`/users/1` 的时候,命中 location /users/ ,执行rewrite 指令, last flag 指示停止后面的rewrite 指令并做内部跳转,匹配到 location /nodejs/ ,经过 proxy_pass 指令,转到 /nodejs/ 。
到了这里,关于nginx http rewrite module 详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!