对于不少Nginx初学者来讲,配置文件是必需要看懂的。可是当公司的Nginx配置文件放在你面前的时候你总会被一些带着"$"符号和一大推看不懂的的正则给正懵逼。没错带着"$"好的你们确定是能首先想到这是一个变量,而后就疯狂的在配置文件里面找关键字,结果一圈照下来啥也没有,这时候大部分人应该就会凭着感受得判断这个变量究竟是什么意思了。其实这也是OK的。可是剩下看不懂正则又应该办呢。这里我就给你们整理了Nginx配置文件中常见的一些变量和正则表达式。php
1、Nginx的内置变量html
$arg_PARAMETER 客户端GET请求中PARAMETER 字段的值android
$args 客户端请求中的参数nginx
$binary_remote_addr 远程地址的二进制表示web
$body_bytes_sent 已发送的消息体字节数正则表达式
$content_length HTTP请求信息中content-length的字段chrome
$content_type 请求信息中content-type字段后端
$cookie_COOKIE 客户端请求中COOKIE头域的值浏览器
$document_root 针对当前请求的根路径设置值缓存
$document_uri 与$uri相同
$host 请求信息中的host头域,若是请求中没有Host行,则等于设置的服务器名
$http_HEADER HTTP请求信息里的HEADER地段
$http_host 与$host相同,可是若是请求信息中没有host行,则可能不一样客户端cookie信息
$http_cookie 客户端cookie信息
$http_referer 客户端是从哪个地址跳转过来的
$http_user_agent 客户端代理信息,也就是你客户端浏览器
$http_via 最后一个访问服务器的IP
$http_x_forwarded_for 至关于访问网路访问的路径
$is_args 若是有args的值,则等于"?",不然为空
$limit_rate 对链接速率的限制
$nginx_version 当前Nginx的版本
$pid 当前Nginx服务器的进程的进程ID
$query_string 与$args相同
$remote_addr 客户端IP地址
$remote_port 客户端的端口
$remote_user 客户端的用户名,用于 auth basic module验证
$request 客户端请求
$request_body 客户端发送的报文体
$request_body_file 发送后端服务器的本地临时缓存文件的名称
$request_filename 当前请求的文件路径名,由root或alias指令与URI请求生成
$request_method 请求后端数据的方法,例如"GET","POST"
$request_uri 请求的URI,带参数,不包含主机名
$scheme 所用的协议,如http或者HTTPS,好比rewrite^(.+)$$scheme://mysite.name$redirect
$sent_http_cache_control 对应http请求头中的Cache-Control,须要打开chrome浏览器,右键检查,选中network,点中其中一个请求的资源
$sent_http_connection 对应http请求中的Connection
$sent_http_content_type 对应http请求中的Content-Type
$sent_last_modified 对应请求中的Last-Modified
$server_addr 服务端的地址
$server_port 请求到达服务器端口号
$server_protocol 请求协议的版本号,HTTP1.0/HTTP1.1
$uri 请求的不带请求参数的URI,可能和最初的值有不一样,好比通过重定向之类的
若是上面的变量尚未找到你想要的结果能够点击右边的这个Nginx官方连接地址--->http://nginx.org/en/docs/varindex.html
2、正则表达式
* 零次或者屡次匹配前面的字符表达式,等效于{0,}.; zo*与“z”和“zoo”匹配
+ 一次或者屡次匹配前面的字符表达式,等效于{1,};zo+与“zoo”匹配可是与“z”不匹配
? 零次或一次匹配前面的字符或子表达式。当该字段紧随任何其余限定符(*、+、?、{n}、{n,}或{n,m})以后时,匹配模式是很是贪婪的,非贪婪模式匹配搜索到的、尽量少的字符串,而默认的贪婪模式匹配搜索到的、尽量多的字符串。zo? 与“z”和“zoo”不匹配;o+?只于“oooooo”中的单个o匹配。而o+与全部的“o”匹配。do(es)?与do或者does中的do匹配
^ 匹配搜索字符串以什么开始。若是将^用做括号表达式中的第一个字符,则会对字符集求反,^\d{3}与搜索字符串开始出的3个数字匹配。[^abc]与除abc觉得的任何字符匹配
$ 匹配搜索字符串以什么结尾,\d{3}$匹配任何3个数字结尾的
. 额这里实际上是一个点号;匹配除了换行符\n以外的任何单个字符
[] 标记括号表达式的开始和结尾,[1-4]与1,2,3,4匹配。[^aAeE],除了a,A,e,E以外的匹配
{} 标记限定符表达式的开始结尾,a{2,3}匹配“aa”和“aaa”
() 标记子表达式的开始和结尾,Nginx服务器使用该元字符保存自表达式以备未来之用A(\d)与“A0”到“A9”匹配,并保存成一个参数
| 这个就能够理解成为一个或匹配了;z|food|cunt 匹配z,food ,cunt
/ 此标识符通常在location中 若是一个/就表示默认匹配这个虚拟主机中的全部资源
\b 与一个字边界匹配,即字与空格间的位置 er\b "never" 中的“er”匹配,但与'verb"中的“er”不匹配
\B 非边界字符匹配,与\b相反
\D 匹配非数字
\w 匹配任意字符
\W 排除A-Z a-z 0-9和下划线之外的任意字符匹配
[a-z] 匹配小写字符
[^a-z] 反字符范围,与上面相反
{n} 正好匹配n次,n是非负整数;o{2}不匹配boy,可是匹配food
{n,} 至少匹配n次
{n,m} 匹配至少n次,最多m次
^和$ 指定搜索字符串的开始和结束为止,这将在搜索字符串包含匹配字符串以外的任何字符时阻止匹配
一些特别的模式修饰符:
(?i) 即匹配时不区分大小写。表示匹配时不区分大小写。
(?s) 即Singleline(单行模式)。表示更改.的含义,使它与每个字符匹配(包括换行 符\n)。
(?m) 即Multiline(多行模式) 。 表示更改^和$的 含义,使它们分别在任意一行的行首和行尾匹配,而不只仅在整个字符串的开头和结尾匹配。(在此模式下,$的 精确含意是:匹配\n以前的位置以及字符串结束前的位置.)
(?x) 表示若是加上该修饰符,表达式中的空白字符将会被忽略,除非它已经被转义。
(?e) 表示本修饰符仅仅对于replacement有用,表明在replacement中做为PHP代码。
(?A) 表示若是使用这个修饰符,那么表达式必须是匹配的字符串中的开头部分。好比说"/a/A"匹配"abcd"。
(?E) 与"m"相反,表示若是使用这个修饰符,那么"$"将匹配绝对字符串的结尾,而不是换行符前面,默认就打开了这个模式。
(?U) 表示和问号的做用差很少,用于设置"贪婪模式"。
Nginx做为一款主流的web服务器,功能强大,在处理请求的方式上也是很是给力的。通常变量和正则出现较多的地方是location区域中,或者是定义日志输出的format格式中。
例子一:Wap端访问PC端域名自动跳转
这个案例的需求是这样子的,假如我使用手机端访问www.baidu.com这条域名,则帮我自动重写为m.baidu.com。而我访问www.souhu.com这条域名,则帮我重写为m.souhu.com这条域名。
if ( $server_name ~ ((|www.|)([if ( $ser| #过滤主域名 if ( $server_name ~ ((www.|)([\S\s]*)) ) { set $domain $3; } #设定初始值 set $temp 0; #判断是否为支付域名 if ( $host ~* (pay|zf) ) { set $temp "${temp}1"; } #判断是不是手机端 if ($http_user_agent ~* (mobile|nokia|iphone|ipad|android|samsung|htc|blackberry)) { set $temp "${temp}2"; } #判断是否跳转 if ( $temp = "02" ) { rewrite ^(.*) https://app.$domain permanent; }
分析过程:
首先,咱们是须要取得主域名部分,那就少不了使用正则去匹配,假如说以www.baidu.com这条域名为例,咱们看到的第一个就是www.这个字段,可是还会存在一种状况就是用户可能会直接输入baidu.com这样子去访问,因此咱们这里是用(www.|)去进行匹配,再而后匹配点这个字段,而下面的$3是表示取第三个括号里的值,最后复值给$a这个变量,接下来就是经过$http_user_agent这个内置变量去进行判断用户是使用什么方式访问,而后在进行重定向操做。
例子二:Nginx的IP白名单
这个案例的需求是这样子的,咱们的后台访问只容许特定的IP进行访问,假如说别的IP进行访问的话咱们将进行跳转到一个别的报错页面,或者直接跳转回首页
#定义初始值 set $my_ip 0; #判断是否为指定的白名单 if ( $http_x_forwarded_for ~* "10.0.0.1|172.16.0.1" ){ set $my_ip 1; } #不是白名单的IP进行重定向跳转 if ( $my_ip = 0 ){ rewrite ^/$ /40x.html; }
分析过程:
这个其实和上面的判断用户是使用电脑访问仍是手机访问是同样的,但惟一的区别在于内置变量不一样,在Nginx中的内置变量里面$http_x_forwarded_for即是为客户访问的真实ip地址,因此咱们使用这个内置变量进行判断就行了,同时添加多了一个初始值;
例子三:重写Url地址,隐藏提交内容
这个案例的需求是这样子的,咱们提交一些表单内容后url地址会显示除部分参数,好比http://baidu.com/index.php?user=admin&pass=123,而咱们须要将url重写为http://baidu.com/index
rewrite ^/(\w+)/(\w+)/z(\d+) /$1/$2/$3/$arg_x/$arg_y? permanent; rewrite ^/(\w+)/(\w+)/(\d+)/(\d+)/(\d+) /$1/$2/$3/$4_$5.png permanent;
分析过程:
首先咱们想一想想url的演变,http://baidu.com/index.php?user=admin&pass=123 => http://baidu.com/index.php/user/admin/pass/123 => http://baidu.com/index,而后咱们根据演变进行一步一步的操做,nginx rewrite正则匹配不会匹配问号后的参数,所以须要使用$arg_{参数名}来保留参数,且匹配规则要以问号结尾;最后匹配一些其余项替换就完成重写了