• -------------------------------------------------------------
  • ====================================

nginx ngx_http_rewrite_module 模块填坑小记

nginx_lua dewbay 5年前 (2019-04-12) 13537次浏览 已收录 0个评论 扫描二维码

在使用 rewrite 模块进行 uri 重写时,得先补充几个知识点

nginx 常用的变量
推荐给 nginx 安装一个 Echo Module,能够非常方便的将我们的请求产生的变量打印出来,nginx 选用 nginx/1.11.10 版本最好,再高一点的版本编译 Echo 模块会报错。nginx 编译成功后添加如下配置。

server {
root /usr/local/nginx/html/;
listen 80;
server_name test.com;
access_log logs/test.com.access.log main;
error_log logs/test.error.log;
location /path/ {
echo “args:” $args;
echo “query_string:” $query_string;
echo “uri:” $uri;
echo “host:” $host;
echo “request_filename:” $request_filename;
echo “request_uri:” $request_uri;
}
}

curl http://test.com/path/file.php?a=1&b=2
args: a=1&b=2
query_string: a=1&b=2
uri: /path/file.php
host: test.com
request_filename: /usr/local/nginx/html/path/file.php
request_uri: /path/file.php?a=1&b=2

rewrite 指令
语法: rewrite regex replacement [flag]
1,第一个注意的地方就是 regex 正则表达是的匹配对象是上文的$uri 变量,即不带 host 和参数的。

rewrite /index.html\?(a=1) index.php?$1 last;
curl test.com/index.html?a=1 是匹配不到不会跳转的
2,默认的情况下请求的参数会跟在 replacement 的后面,如果重定向后的地址想省略原始请求参数在替换的 replacement 后面加上?即可

请求 test.com/post-21.html?a=1&b=2 会被重定向为 test.com/post.php?page=21&a=1&b=2

rewrite /post-(\d+).html /post.php?page=&1 permanent;

如果想去掉重定向后的 a=1&b=2 参数,在 replacement 加上?

rewrite /post-(\d+).html /post.php?page=&1? permanent;
3,flag:确定重定向的动作
last:停止下面的执行下面的ngx_http_rewrite_module 指令集(包括 rewrite,if,return,set 这些指令),并开始用重写后新的 uri 去匹配 location。
break:停止下面的执行下面的ngx_http_rewrite_module 指令集。
redirect:服务器发起 302 临时重定向请求重写的地址
permanent:服务器发起 301 永久重定向请求重写的地址

last 和 break 当出现在 location 之外时,两者的作用是一致的没有任何差异。当出现在 location 内部时,两者就存在了差异。
last: 使用了 last 指令,rewrite 后会跳出 location 作用域,重新开始再走一次刚刚的行为
break: 使用了 break 指令,rewrite 后不会跳出 location 作用域。它的生命也在这个 location 中终结。
ngx_http_rewrite_module 任然可以执行,比如 proxy_pass ,fastcgi_pass

对用户使用浏览器访问的 url 来说,last,break 都不会改变地址栏的地址。并且不执行后续的 rewrite 指令,但是 last 会开始用重写后新的 uri 去匹配 location,如何理解?下面这个例子可以帮助理解。

rewrite /test/.* /index.html break;
location /test/ {
return 508;
}
location /break/ {
rewrite ^/break/(.) /test/$1 break; return 402; } location /last/ { rewrite ^/last/(.) /test/$1 last;
return 403;
}
请求: http://test.com/break/*
返回:404
请求: http://test.com/last/*
返回:508
请求: http://test.com/test/*
返回:200 (返回 index.html)
原因:根据上述内容,break 与 last 都停止处理后续 rewrite 指令集,不同之处在与 last 会重新发起新的请求,而 break 不会。当请求 break 时,如匹配内容存在的话,可以直接请求成功,返回 200;而如果请求内容不存在,则返回 404。当请求为 last 的时候,会对重写的新 uri 重新发起请求,只是重新查找 location 匹配,如上例则返回 508。
4,location 与 rewrite 一些想法

4.1 $uri 与 $request_filename 在 last,break 改变 uri 后重新查找匹配是变化,但是$request_uri 不会变。接着
上例,在请求: http://test.com/last/* 变成新的 uri 后重新查找时:
uri: /test/*
request_filename: /usr/local/nginx/html/test/*
request_uri: /last/* (不变)
4.2 location 匹配的是$uri,但是 rewrite 匹配的是 request_uri
4.3 rewrite 匹配的优先级高于 location


露水湾 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:nginx ngx_http_rewrite_module 模块填坑小记
喜欢 (0)
[]
分享 (0)
关于作者:
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址