Location 语法解释

Location 语法解释

Scroll Down

Location 语法解释

location 大致可以分成3种

  • 精准匹配
  • 一般匹配
  • 正则匹配
location [=|~|~*|^~] /uri/ { … }

location = url { … } # 精准匹配
location  url { … } # 一般匹配
location ~ url { … } # 正则匹配

符号解释

符号解释
=开头表示精确匹配
^~开头表示 url 以某个常规字符串开头,理解为匹配 url 路径即可。
~开头表示区分大小写的正则匹配
~*开头表示不区分大小写的正则匹配
! ~ 和 ! ~ *分别为区分大小写不匹配及不区分大小写不匹配 的正则
/通用匹配,任何请求都会匹配到

如何发挥作用

首先看有没有精准匹配,如果有则停止匹配过程

location = patt {
	config A
}

如果 $url = patt,那么算匹配成功,则使用 config A。

示例:


location =/ {
	root	/var/www/html/;
	index	index.htm index.html;
}

location / {
	root	/usr/local/nginx/html;
	index	index.html index.htm;
}

如果访问 http://xxx.com/

定位流程是:

  1. 精准匹配中 “/”,得到 index 页为 index.html
  2. 再次访问 /index.htm ,此次内部跳转 URI 已经是 “/index.htm”,目前根目录为 /usr/local/nginx/html
  3. 最终结果,访问/usr/local/nginx/html 下的 index.htm。

现在加入正则,示例1:


location / {
	root	/usr/local/nginx/html;
	index	index.html index.htm;
}

location ~ image {
	root	/var/www/html/;
	index	index.html;
}

如果此时访问 http://xx.com/image/test.png (假设此时 /var/www/html/ 下有 test.png 文件)

此时,“ / ”与 “ /image/test.png ”匹配,同时,“ image ”正则与“ /image/test.png ”也能匹配。最终图片会真正访问 /var/www/html/image/test.png

示例2:


location / {
	root	/usr/local/nginx/html;
	index	index.html index.htm;
}

location /dudulu {
	root	/var/www/html/;
	index	index.html;
}

访问 http://xx.com/image/dudulu

对于 uri “ /dudulu ”,两个 location 的 patt ,都能匹配到他们,即 “ / ”能从左前缀匹配 “ /dudulu ”,“ /dudulu ”也能左前缀匹配“ /dudulu ”。

此时真正访问的是 /var/www/html/index.html ,原因:“ /dudulu ”匹配的更长,所有使用这个。

下面从网上找到三个匹配规则定义


#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
    proxy_pass http://tomcat:8080/index
}
 
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {                              //以xx开头
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {     //以xx结尾
    root /webroot/res/;
}
 
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
location / {
    proxy_pass http://tomcat:8080/
}

总结:location 的命中过程

  1. 先判断精准命中,如果命中,立即返回结果并结束解析过程
  2. 判断普通命中,若干个如果有多个命中,“记录”下来“最长”的命中结果(注意:记录但不结束,最长的为准)
  3. 继续判断正则表达式的解析结果,按配置里的正则表达式顺序为准,由上到下开始匹配,一旦匹配成功一个,立即返回结果,并且结束解析过程

延伸:1、普通命中,顺序无所谓,是因为按命中的长短来确定的。2、正则命中,顺序有所谓,因为从前往后命中。

Rewrite 重写 语法解释

重写中用到的指令

指令解释
if () {}设定条件,在进行重写
set设置变量
return返回状态码
break跳出 rewrite
rewrite重写

if 语法的格式


#if 空格 {条件}{
#	重写模式
#}

判断的表达式条件

  • -f和!-f用来判断是否存在文件
  • -d和!-d用来判断是否存在目录
  • -e和!-e用来判断是否存在文件或目录
  • -x和!-x用来判断文件是否可执行
  • = 用来判断相等,用于字符串的比较
  • ~ 用来正则匹配 (区分大小写)(~ * 不区分大小写)

示例:


if ( $remote_addr = 192.168.1.14 ){
	return 430;
}

if ( $http_user_agent ~ MSIE ){
	rewrite ^.*$/dudulu.html;
	break; # 不加 break 会循环重定向
}

if ( !-e $document_root $fastcgi_scrpt_name ){
	rewrite ^.*$/404.html break;
}

# 注:此处还要加 break

以 xx.com/dudulu.html 这个不存在的页面为例

观察服务器日志文件可以发现,日志中显示的访问路径依然是 GET /dudulu.html HTTP/1.1

提示:服务器内部的 rewrite 和 302 跳转不一样

跳转的话 url 都变了,变成重新 http 请求 404.html ,而内部的 Rewrite,上下文没变,就是说 astcgi_scrpt_name 仍然是 dudulu.html ,因此会循环重定向。