rewrite 介绍
- nginx的重写模块是一个简单的正则表达式匹配与一个虚拟堆叠机结合。依赖于PCRE库,因此需要安装pcre。根据相关变量重定向和选择不同的配置,从一个location跳转到另一个location,不过这样的循环最多可以执行10次,超过后nginx将返回500错误。同时,重写模块包含set指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。
rewrite 模块指令
1.rewrite
- 语法
rewrite <regex> <replacement> [flag];
关键字 匹配uri的正则 替代内容 flag标记
- 例子
rewrite ^/(.*) http://www.adc.com/$1 permanent;
- 配置段: server,location,if
- regex 语法
- 是一个正常通用的正则表达式不像localtion中有特殊语义的语法,匹配完整的域名和后面的路径地址
- ()里的内容是可以&1(&2,$3)的形式提供给replacement段使用
replacement
- 如果replacement以http://开头,请求将被重定向,并且不再执行多余的rewrite指令
flag标记说明
last #本条规则匹配完成后,会根据replacement的值继续向下匹配新的location URI规则,这是和break标记不同的地方
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址,如果替换字段用http://开头则被使用。
permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
2.if
语法:
if (condition) { … }
默认值:none
- 配置段:server, location
- 注意 if 与() 以及内部的条件间要加空格,不可以贴在一起,否则编译不通过
判断的条件:
1.正则表达式匹配:
= :等值比较;
!= : 不等时返回真;
~:与指定正则表达式模式匹配时返回“真”,判断匹配与否时区分字符大小写;
~*:与指定正则表达式模式匹配时返回“真”,判断匹配与否时不区分字符大小写;
!~:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时区分字符大小写;
!~*:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时不区分字符大小写;2.文件及目录匹配判断:
-f, !-f:判断指定的路径是否为存在且为文件;
-d, !-d:判断指定的路径是否为存在且为目录;
-e, !-e:判断指定的路径是否存在,文件或目录均可;
-x, !-x:判断指定路径的文件是否存在且可执行;例子
if ( $http_x_forwarded_for !~* ^192\.168\.0\.1.* ) {
......
}
if ( $remote_addr = 222.222.222.222){
.......
}
3.break
- 该指令的作用是完成当前的规则集,不再处理其它rewrite指令
- 该break与rewrite中的flag标签的break没有任何关系
- 语法:
break;
- 配置段:server,location,if
- 例子
location / {
rewrite ^/(.*) http://www.adc.com/$1 permanent;
break;
}
4.return
- 停止处理并为客户端返回状态码。非标准的444状态码将关闭连接,不发送任何响应头。可以使用的状态码有:204,400,402-406,408,410, 411, 413, 416与500-504。如果状态码附带文字段落,该文本将被放置在响应主体。相反,如果状态码后面是一个URL,该URL将成为location头补值。没有状态码的URL将被视为一个302状态码。
- 语法:
return code
- 配置段:server, location, if
例子
- 有http://开头时的确是完全重定向到新链接上了
- 关于flag所导致的结果,首先permanent与last最终都能转到本地的8888服务端口,其次permanent是301重定向的意思,所以客户端会修改uri,last是按新的uri重新访问server,并没有通过客户端重定向,所以客户端上的url地址不会改变
server {
listen 8861;
server_name abcd.com;
set $hello 'world';
location / {
# 最终url http://www.baidu.com/...
if ( $hello = "hello" ) {
rewrite ^/(.*)$ http://www.baidu.com/$1 break;
}
# 最终url abcd.com:8861/index/getInfo/
if ( $hello = "world" ) {
rewrite ^/(.*)$ /index/getInfo/ permanent;
}
# url不改变
if ( $hello = "hello world" ) {
rewrite ^/(.*)$ /index/getInfo/ last;
}
}
location /index {
proxy_pass http://localhost:8888;
}
}
补充
- 对于rewrite 模块以上只是介绍了使用方式,但是对于一些指令标签的含义本人也是有一些混沌,上述的表述中不能详尽。有不明白还是以实测为主,选择对应配置。
- 关于rewrite的日志配置在 nginx日志系统 中的rewrite_log 模块中有详述。