nginx rewrite规则
指令:
set 用来设置变量。
if 用来判断一些在rewrite语句中无法直接匹配的条件。
用法:if(条件){......}
当if表达式中的条件为true,则执行if块中的语句,当表达式只是一个变量时,如果值为空或者任何以0开头的字符串都会当做false。
直接比较内容时,使用 =和!=
使用正则表达式匹配时使用:
~区分大小写匹配
*不区分大小写匹配
!~区分大小写不匹配
!~*不区分大小写不匹配
检测文件和目录:
-f 检测文件存在
-d 检测目录存在
-e 检测文件,目录或者符号链接存在
-x 检测文件可执行
示例:
location = / {
#精确匹配/,主机名后面不能带任何字符串
[ configuration A ]
}
location / {
#因为所有的地址都以/开头,所以这条规则将匹配到所有请求
#但是正则和最长字符串会优先匹配
[ configuration B ]
}
location /documents/ {
#匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
#只有后面的正则表达式没有匹配到时,这一条才会采用这一条
[ configuration C ]
}
location /documents/abc {
#匹配任何以 /documents/开头的地址,匹配符合以后,还要继续往下搜索
#只有后面的正则表达式咩有匹配到时,这一条才会采用这一条
[ configuration CC ]
}
location ^~ /images/ {
#匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
#匹配所有以gif,jpg,或jpeg结尾的请求
#然而,所有请求 /images/ 下的图片会被config D 处理,因为 ^~ 到达不了这一条正则
[ configuration E ]
}
location /images/ {
#字符匹配到 /images/ ,继续往下,会发现 ^~ 存在
[ configuration F ]
}
location /images/abc {
#最长字符匹配到/images/abc,继续往下,会发现 ^~存在
#F与G的放置顺序是没有关系的
[ configuation G ]
}
locaiton ~ /images/abc/ {
#只有去掉 configuration D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则采用
[ configuration H ]
}
以 = 号开头的表示精确匹配。 如A中只匹配根目录结尾的请求,后面不能带任何字符串。 ^~ 开头表示uri
以某个常规字符串卡头,不是正则匹配。
~ 开头表示区分大小写的正则匹配。
~* 开头表示不区分大小写的正则匹配。
/ 通用匹配,如果没有其他匹配,任何请求都会匹配到。
顺序优先级:
(location = )> (location 完整路径)> (location ^~ 路径)> (location ~,~* 正则顺序)> (location 部分起始路径) > /
/ --> configuration A
精确完全匹配,即使/index.html也匹配不了。
/downloads/download.html ---> configuration B
匹配B以后,往下没有任何匹配,采用B
/images/1.gif ---> configuration D
匹配到F,往下匹配到D,停止往下
/images/abc/def --> configuration D
最长匹配到G,往下匹配D,停止往下。你可以看到,任何以/images/开头的都会匹配到D并停止,FG写在这里没有任何意义的,H是永远轮不到的,这里只是为了说明匹配顺序。
/documents/document.html ----> configuration C
匹配到C,往下没有任何匹配,采用c
/documents/1.jpg ----> configuration E
匹配到c,往下正则匹配到E
/documents/abc.jpg ---> configuration CC
最长匹配到C,往下增则顺序匹配到CC,不会往下到E
实际使用建议:
所以实际使用中,个人觉得至少有三个匹配规则定义,如下:
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
第一个必选规则
location = / {
proxy_pass http://tomcat:8080/index
}
第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
proxy_pass http://tomcat:8080/ }
举例:
if ( $http_user_agent ~ MSIE ) { rewrite ^(.*)$ /msie /$1 break; }
如果UA包含“MSIE”,rewrite请求到/msie目录下
if ( $http_cookie ~* "id=([^;]+)(?:;|$)" ) { set $id $1; }
如果cookie匹配正则,设置变量$id等于正则引用部分
if ( $request_method = post ) { return 405; }
如果提交方法为POST,则返回状态405
if ( ! -f $request_filename ) { break; proxy_pass http://127.0.0.1 }
如果请求文件名不存在,则反向代理localhost
if ( $args ~ post=140 ) { rewrite ^ http://example.com / permanent; }
如果query string中包含“post=140”,永久重定向到example.com
if ( $slow ) { limit_rate 10k; }
限速为10K
if ( ! -f $request_filename ) {
break;
proxy_pass http://127.0.0.1; }
如果请求的文件名不存在,则反向代理到localhost,这里的break也是停止rewrite检查
防盗链
location ~* \.( gif|jpg|png|swf|flv )$ {
valid_referers none blocked www.jefflei.com www.baidu.com;
if ( $invalid_referer ) {
return 404;
}
}
return 可用来直接设置http返回状态
break 立即停止rewrite检测。
rewrite
用法:rewrite 正则 替换 标志位
其中标志位有四种:
break 停止rewrite检测,包含break的语句被执行时,该语句就是rewrite最终的结果
last 停止rewrite检测,但是包含last的语句不一定是最终结果 。
location
redirect 返回302临时重定向,一般用于重定向到完整的URL
permanent 返回301永久重定向,一般用于重定向到完整的URL
用作if判断的全局变量
$args 这个变量等于请求行中的参数,同$query_sting。
$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_addr 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name 服务器名称。
$server_port 请求到达服务器的端口号。
$request_uri 包含请求参数的原始RUI,不包含主机名。
$uri 不带请求参数的当前uri。
$document_uri 与$uri相同。
常用正则:
. 匹配除换行符以外的任意字符
? 重复0次或1次
+ 重复1次或更多次
* 重复0次或更多次
| 用或的方式查找多个字符的字符串
\d 匹配数字
^ 匹配字符串的开始
$ 匹配字符串的介绍
{n} 重复n次
{n,} 重复n次或更多次
[c] 匹配单个字符c
[a-z] 匹配a-z小写字母的任意一个
[^abc] 匹配不包含^后的任意字符,在中括号里^符号为取反
a\{a,m\} 重复n次到m 次
a\{n,\} 重复最少n次
a\{n\} 只重复n次
a\{,m\} 最多m次