[深] nginx rewrite规则(23)
获取全套nginx教程,请访问瓦力博客
nginx Rewrite规则可以让网站的url中达到某种状态时定向/跳转到某个规则,可以实现很多功能。
- url访问跳转,支持开发设计,页面跳转、兼容性支持、展示效果、301重定向等。
- SEO优化
- 维护,流量转发
- 安全,如伪静态
内置的全局变量
变量名 | 描述 |
---|---|
$args | 这个变量等于请求行中的参数,同$query_string |
$content_length | 请求头中的Content-length字段 |
$content_type | 请求头中的Content-Type字段 |
$document_root | 当前请求在root指令中指定的值 |
$host | 请求主机头字段,否则为服务器名称 |
$http_user_agent | 客户端agent信息 |
$http_cookie | 客户端cookie信息 |
$limit_rate | 这个变量可以限制连接速率 |
$request_method | 客户端请求的动作,通常为GET或POST |
$remote_addr | 客户端的IP地址 |
$remote_port | 客户端的端口 |
$remote_user | 已经经过Auth Basic Module验证的用户名 |
$request_filename | 当前请求的文件路径,由root或alias指令与URI请求生成 |
$scheme | HTTP方法(如http,https) |
$server_protocol | 请求使用的协议,通常是HTTP/1.0或HTTP/1.1 |
$server_addr | 服务器地址,在完成一次系统调用后可以确定这个值 |
$server_name | 服务器名称 |
$server_port | 请求到达服务器的端口号 |
$request_uri | 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz” |
$uri | 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html” |
$document_uri | 与$uri相同 |
1.rewrite模块
rewrite配置项属于ngx_http_rewrite_module
模块传送门{:target="_blank"}
rewrite
Syntax: rewrite regex replacement [flag]; #匹配规则 定向路径 标志参数
Default: —
Context: server, location, if
flag选项 | 描述 |
---|---|
break | 匹配到之后会在替换后的目录下面去查找 |
last | 匹配到之后会在替换后重新用新地址发起请求 |
redirect | 返回带有302代码的临时重定向;如果替换字符串不以“http://”,“https://”或“$scheme” |
permanent | 返回301代码的永久重定向 |
break
停止处理当前的ngx_http_rewrite_module指令集。
Syntax: break;
Default: —
Context: server, location, if
if
如果为true,则执行在大括号内指定的此模块指令,并在if指令内为该请求分配配置
Syntax: if (condition) { ... }
Default: —
Context: server, location
条件可以是以下任何一种:
- 如果变量的值为空字符串或“0”,则为false;
- 使用
=
和`!=运算符比较变量和字符串; - 使用
~
(对于区分大小写的匹配)和~*
(对于不区分大小写的匹配)运算符,将变量与正则表达式进行匹配。正则表达式可以包含可供以后在9变量中重用的捕获。负操作符!~
和!~*
也可用。如果正则表达式包含}
或;
字符,则整个表达式应包含在单引号或双引号中。 - 使用
-f
和!-f
运算符检查文件是否存在 - 使用
-d
和!-d
运算符检查目录是否存在 - 使用
-e
和!-e
运算符检查文件,目录或符号链接是否存在 - 使用
-x
和!-x
运算符检查可执行文件。
return
该指令用于结束规则的执行并返回状态码给客户端。
Syntax: return code [text];
return code URL;
return URL;
Default: —
Context: server, location, if
set
Syntax: set $variable value;
Default: —
Context: server, location, if
2.调试rewrite是否正确
nginx中要检测rewrite是否正确,就需要开启rewrite_log
才能排错,rewrite_log会打印错误。检测完后,建议将rewrite_log关闭。
rewrite_log
Syntax: rewrite_log on | off;
Default: rewrite_log off;
Context: http, server, location, if
示例:
rewrite_log on;
error_log /var/log/nginx/rewrite.log notice;
3.break和last区别
rewrite里面flag中break
和last
是什么区别?请看下面的例子
root /opt/app/code;
location ~ ^/break {
rewrite ^/break /test/ break;
}
location ~ ^/last {
rewrite ^/last /test/ last;
}
location /test/ {
default_type application/json;
return 200 '{"status":"success"}';
}
break
是停止处理当前的ngx_http_rewrite_module指令集,就是说不会在向下匹配新的location,last
停止处理当前的ngx_http_rewrite_module指令集并开始搜索与更改的URI匹配的新位置;
假设我们在页面上访问的url是http://walidream.com/break
,根据上面的nginx规则,肯定会匹配到第一个,匹配到第一个之后,根据rewrite正则,url由原来的/break
变为/test/
但是在root/opt/code/
目录
下,没有找到/test/
目录下面的内容,所以nginx会返回404错误码。
如果将http://walidream.com/break
换成http://walidream.com/last
,根据上面的nginx规则,会匹配到第二个location,根据location里面rewrite正则,url由原来的/last
变为/test/
,但是会重新
匹配loction中,可以简单理解就是将替换后urlhttp://walidream.com/test
重新发起一次请求。这个时候会匹配到第三个loaction,根据location里的rewrite正则,会反会200码,并且会返回json内容'{"status":"success"}'
4.redirect和permanent区别
rewrite里面flag中redirect
(临时重定向)和permanent
(永久重定向)是什么区别?请看下面的例子
location ~ ^/imooc {
rewrite ^/imooc http://www.imooc.com/ redirect;
}
location ~ ^/wali {
rewrite ^/wali http://www.imooc.com/ permanent;
}
redirect
会返回带有302代码的临时重定向,permanent
会返回带有301代码的永久重定向。
假设我们在页面上访问url是http://walidream.com/imooc
,根据nginx匹配规则会匹配到第一个location,会重写url,返回一个带有302状态代码,重写后的url是http://www.imooc.com
,浏览器会重定向到这个网址,
当我们再次访问http://walidream.com/imooc
,nginx还是会先匹配在替换然后重定向。
如果在页面上输入http://walidream.com/wali
,根据nginx匹配规则会匹配到第二个location,会重写url,返回一个带有301状态码,重写后的url是http://www.imooc.com
,浏览器会重新定向到这个网址,
当我们再次访问http://walidream.com/wali
,这个时候浏览器根本不会在经过nginx,而是直接有浏览器重定向到这个网址。
5.rewrite优先级
我们知道rewrite的执行环境是server,location,if。那就有一个问题,当这三个执行环境中都存在rewrite规则,那么执行优先级是什么。
server > location > if
6.利用变量或者return调试
不知道大家写了这么长时间的nginx有没有感觉nginx很难调试,调试一个错误要很长时间。比如上面rewrite 这个就没办法检测自己规则是否在的正确,没有输出,所以要验证rewrite正则是否正确,就要打开
rewrite_log日志,如果匹配错了,日志会记录错误信息。
向一般的检测语法,我们可以利用变量return 返回。
location ~ ^/wali {
default_type application/json;
return 200 '{"status":"success"}';
}
location ~ ^/yagm {
default_type application/json;
return 200 '{"status":"error"}';
}
这样有时候在调试时会让我们变得稍微方便一点,还有nginx扩展模块如echo就能直接输出内容或者打印内部变量。我们调试起来就更方便了,下面小菜抽一点时间,来讲讲如何安装echo模块。nginx echo传送门{:target="_blank"}