语法规则: location [=|~|~*|^~] /uri/ { … }
- = 开头表示精确匹配
- ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
- ~ 开头表示区分大小写的正则匹配
- ~* 开头表示不区分大小写的正则匹配
- !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
- / 通用匹配,任何请求都会匹配到。
多个location配置的情况下匹配顺序为(仅供参考):
首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
例子,有如下匹配规则:
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
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/
}
location uri正则表达式
-
. :匹配除换行符以外的任意字符
-
? :重复0次或1次
-
+ :重复1次或更多次
-
* :重复0次或更多次
-
\d :匹配数字
-
^ :匹配字符串的开始
-
$ :匹配字符串的结束
-
{n} :重复n次
-
{n,} :重复n次或更多次
-
[c] :匹配单个字符c
-
[a-z] :匹配a-z小写字母的任意一个
-
(a|b|c) : 属线表示匹配任意一种情况,每种情况使用竖线分隔,一般使用小括号括括住,匹配符合a字符 或是b字符 或是c字符的字符串
-
\ 反斜杠:用于转义特殊字符
小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。
Nginx配置proxy_pass转发的/路径问题
在nginx中配置proxy_pass时,如果是按照^~匹配路径时,要注意proxy_pass后的url最后的/,当加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路径部分也给代理走。
location ^~ /static_js/
{
proxy_cache js_cache;
proxy_set_header Host js.test.com;
proxy_pass http://js.test.com/;
}
如上面的配置,如果请求的url是http://servername/static_js/test.html
会被代理成http://js.test.com/test.html
而如果这么配置
location ^~ /static_js/
{
proxy_cache js_cache;
proxy_set_header Host js.test.com;
proxy_pass http://js.test.com;
}
则会被代理到http://js.test.com/static_js/test.htm
当然,我们可以用如下的rewrite来实现/的功能
location ^~ /static_js/
{
proxy_cache js_cache;
proxy_set_header Host js.test.com;
rewrite /static_js/(.+)//1 break;
proxy_pass http://js.test.com;
}
@开头的,如果请求的 URI 存在,则本 nginx 返回对应的页面;如果不存在,则把请求代理到baidu.com 上去做个弥补,其实就是做了一个容错,把找不到的url全部转发到fallback的反向代理服务器去。
nginx的其他配置信息介绍
三、ReWrite语法
last
– 基本上都用这个Flag。break
– 中止Rewirte,不在继续匹配redirect
– 返回临时重定向的HTTP状态302permanent
– 返回永久重定向的HTTP状态301
1、下面是可以用来判断的表达式:
-f
和!-f
用来判断是否存在文件-d
和!-d
用来判断是否存在目录-e
和!-e
用来判断是否存在文件或目录-x
和!-x
用来判断文件是否可执行
2、下面是可以用作判断的全局变量
例:http://localhost:88/test1/test2/test.php
$host:localhost $server_port:88 $request_uri:http://localhost:88/test1/test2/test.php $document_uri:/test1/test2/test.php $document_root:D:\nginx/html $request_filename:D:\nginx/html/test1/test2/test.php
四、Redirect语法
server { listen 80; server_name start.igrow.cn; index index.html index.php; root html; if ($http_host !~ "^star\.igrow\.cn$" { rewrite ^(.*) http://star.igrow.cn$1 redirect; } }
五、防盗链
location ~* \.(gif|jpg|swf)$ { valid_referers none blocked start.igrow.cn sta.igrow.cn; if ($invalid_referer) { rewrite ^/ http://$host/logo.png; } }
六、根据文件类型设置过期时间
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ { if (-f $request_filename) { expires 1h; break; } }
七、禁止访问某个目录
location ~* \.(txt|doc)${ root /data/www/wwwroot/linuxtone/test; deny all; }
附:一些可用的全局变量
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 themachine’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 #请求到达服务器的端口号。
用例
访问url的时候,会出现:http://www.test.com/html/service/a.html,缺乏美观性,而且也暴露了目录结构。那就想办法去掉中间的 html,将连接变为:http://www.test.com/service/a.html。想要实现此变化,需要对nginx的location进行配置。
# 匹配/service/开头的任何查询并且停止搜索。任何正则表达式将不会被测试。
location ^~ /service/ {
#将service指向/html/service目录
#测试过程中,可以用 在结尾加上 redirect 查看跳转结果
#rewrite ^/service/(.*)$ /html/service/$1$2 redirect;
rewrite ^/service/(.*)$ /html/service/$1$2;
}