☺
Nginx中if语句中的判断条件
if语句中的判断条件(nginx)
正则表达式匹配:
==:等值比较; ~:与指定正则表达式模式匹配时返回“真”,判断匹配与否时区分字符大小写; ~*:与指定正则表达式模式匹配时返回“真”,判断匹配与否时不区分字符大小写; !~:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时区分字符大小写; !~*:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时不区分字符大小写;
- 文件及目录匹配判断:
-f, !-f:判断指定的路径是否为存在且为文件;
-d, !-d:判断指定的路径是否为存在且为目录;
-e, !-e:判断指定的路径是否存在,文件或目录均可;
-x, !-x:判断指定路径的文件是否存在且可执行;
举例
有些公司可能有这样的需求,如:我的网站或者网页游戏需要更新,所有的用户或者玩家访问到的是一个停服更新页面,而本公司的IP可以访问,甚至说本公司的某个内网IP可以访问,用于确认更新成功与否,针对这个问题写了如下的访问控制规则:
可以作为nginx的停服更新使用,仅允许222.222.222.222或者内网的两个IP访问,其他IP都rewrite到停服页面
Nginx.conf中加入在你项目的正确位置set $my_ip ''; if ( $remote_addr = 222.222.222.222){set $my_ip 1;} #注意这里的$remote_addr如何用了负载均衡的话,这里应该是$http_x_forwarded_for if ( $remote_addr = 192.168.1.170 ){ set $my_ip 1;} if ( $remote_addr = 192.168.1.169 ){ set $my_ip 1;} if ( $my_ip != 1) {rewrite ^/design/(.*)\.php$ /tingfu.html?$1&;} #将*.php转到tingfu.html
访问某个php应用的时候我只想让内部的某个IP访问,其他的IP都转到另一个PHP上。如下:
访问test.php,且IP不等222.222.222.222的跳转到55555.php:set $test ‘’;
if ( $request_uri ~* /img/test.php ) {set $test P;
}
if ( $http_x_forwarded_for !~* ^222\.222\.222\.222.* ) {
set $test "${test}C";
}
if ( $test = PC ) { #当条件符合 访问test.php并且 ip不是222.222.222.222的 转发到55555.php
rewrite ^(.*)$ /img/55555.php permanent;
}
区分PC或手机访问不同网站
location / { proxy_pass http://10.10.100.60:8183; if ( $http_user_agent ~* "(mobile|nokia|iPhone|ipad|android|samsung|htc|blackberry)" ) { rewrite ^/$ http://www.baidu.com; } index index.html index.htm; }
if判断&&(并且)写法【post 提交并且是php文件的把变量$allowss设置成false】
set $allowphp ''; if ($request_method ~ ^(POST)$) { set $allowphp p; } if ( $request_filename !~ \.php$) { set $allowphp "${allowphp}c"; } if ( $allowphp = pc) { set $allowss false; }
nginx if判断||(或)写法【ip地址222.186.34.41或180.97.106.37的把变量$allowss设置成false】
set $allowss true; if ($http_x_forwarded_for ~ " ?222\.186\.34\.41$") { set $allowss false; } if ($http_x_forwarded_for ~ " ?180\.97\.106\.37$") { set $allowss false; }
加上下面的代码,可以拒绝访问。
if ($allowss = false) {
return 403;
}
- post请求转发维持数据
用301重定向给网站更换新域名get有效,但是post会失效变成get怎么办?针对301的response,浏览器的行为就是发送GET请求Location中的URL。
如果需要保持原来的POST方法不变去重新请求,需要使用307,但这未必是你想要的,因为根据标准浏览器针对307的POST请求需要用户明确确认(比如会弹一个alert)。可以用代理的方式去解决(proxy_pass)。
server {
server_name gaogd.com;
location / {
if ($request_method ~ ^(POST)$) {
proxy_pass http://www.gaogd.com;
break ;
}
rewrite ^/(.*)$ http://www.gaogd.com/$1 permanent;
}
nginx参数作用
$arg_PARAMETER #这个变量包含GET请求中,如果有变量PARAMETER时的值。
$args #这个变量等于请求行中(GET请求)的参数,例如foo=123&bar=blahblah;
$binary_remote_addr #二进制的客户地址。
$body_bytes_sent #响应时送出的body字节数数量。即使连接中断,这个数据也是精确的。
$content_length #请求头中的Content-length字段。
$content_type #请求头中的Content-Type字段。
$cookie_COOKIE #cookie COOKIE变量的值
$document_root #当前请求在root指令中指定的值。
$document_uri #与$uri相同。
$host #请求主机头字段,否则为服务器名称。
$hostname #Set to the machine's hostname as returned by gethostname
$http_HEADER
$is_args #如果有$args参数,这个变量等于”?”,否则等于”",空值。
$http_user_agent #客户端agent信息
$http_cookie #客户端cookie信息
$limit_rate #这个变量可以限制连接速率。
$query_string #与$args相同。
$request_body_file #客户端请求主体信息的临时文件名。
$request_method #客户端请求的动作,通常为GET或POST。
$remote_addr #客户端的IP地址。
$remote_port #客户端的端口。
$remote_user #已经经过Auth Basic Module验证的用户名。
$request_completion #如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty)。
$request_method #GET或POST
$request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。
$request_uri #包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。不能修改。
$scheme #HTTP方法(如http,https)。
$server_protocol #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr #服务器地址,在完成一次系统调用后可以确定这个值。
$server_name #服务器名称。
$server_port #请求到达服务器的端口号。
$uri #不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。该值有可能和$request_uri 不一致。$request_uri是浏览器发过来的值。该值是rewrite后的值。例如做了internal redirects后。
重定向举例
rewrite同时参数保留
把http://example.com/test.php?para=xxx 重定向到 http://example.com/new
若按照默认的写法:rewrite ^/test.php(.) /new permanent;
重定向后的结果是:http://example.com/new?para=xxx
如果改写成:rewrite ^/test.php(.) /new? permanent;
那结果就是:http://example.com/new
所以,关键点就在于“?”这个尾缀。假如又想保留某个特定的参数,那又该如何呢?可以利用Nginx本身就带有的$arg_PARAMETER参数来实现。
例如:
把http://example.com/test.php?para=xxx&p=xx 重写向到 http://example.com/new?p=xx
可以写成:rewrite ^/test.php /new?p=$arg_p? permanent;
只求结果的朋友可以直接忽略前面的内容,看这里:
rewrite ^/test.php /new permanent; //重写向带参数的地址
rewrite ^/test.php /new? permanent; //重定向后不带参数
rewrite ^/test.php /new?id=$arg_id? permanent; //重定向后带指定的参数
permanent是永久重定向参数,根据需要去掉也可以,不过最好是带有。
首先Apache的Rewite规则差别不是很大,但是Nginx的Rewrite规则比Apache的简单灵活多了
Nginx可以用if进行条件匹配,语法规则类似C
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
Rewrite的Flags
last - 完成重写指令后,搜索相应的URI和位置。相当于Apache里的[L]标记,表示完成rewrite,不再匹配后面的规则。
break - 中止Rewirte,不在继续匹配。
redirect - 返回临时重定向的HTTP状态302。
permanent - 返回永久重定向的HTTP状态301。
ZEND Framework的重定向规则
案例一:
全部重定向到 /index.php
rewrite ^/(.*) /index.php?$1&;
案例二:
如果文件或目录不存在则重定向到index.php
if (!-e $request_filename) {
rewrite ^/(.*) /index.php?$1&;
}
WordPress的重定向规则
案例一
http://www.wemvc.com/12 重定向到 http://www.wemvc.com/index.php?p=12
if (!-e $request_filename) {
rewrite ^/(.+)$ /index.php?p=$1 last;
}
案例二
与zendframework配置很像
if (!-e $request_filename) {
rewrite ^/(.*) /index.php?$1&;
}
Discuz完整的Rewrite for Nginx规则
if (!-f $request_filename) {
rewrite ^/archiver/((fid|tid)-[\w\-]+\.html)$ /archiver/index.php?$1 last;
rewrite ^/forum-([0-9]+)-([0-9]+)\.html$ /forumdisplay.php?fid=$1&page=$2 last;
rewrite ^/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /viewthread.php?tid=$1&extra=page=$3&page=$2 last;
rewrite ^/space-(username|uid)-(.+)\.html$ /space.php?$1=$2 last;rewrite ^/tag-(.+)\.html$ /tag.php?name=$1 last;
}
文件及目录匹配【参数释义】
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
正则表达式全部符号解释
~ 为区分大小写匹配
~* 为不区分大小写匹配
!~和!~* 分别为区分大小写不匹配及不区分大小写不匹配
(pattern) 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript. 中使用 SubMatches 集合,在JScript. 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 ‘\(' 或 ‘\)'。
^ 匹配输入字符串的开始位置。
$ 匹配输入字符串的结束位置。