location匹配

匹配的符号说明

表示符号

符号说明

=

表示精确匹配,只有完全匹配上才能生效

^~

表示uri以某个常规字符串开头

~

正则匹配(区分大小写)

~*

正则 (不区分大小写)

! ~

区分大小写不匹配的正则

! ~ *

不区分大小写不匹配的正则

/

任何请求都会匹配

匹配优先级

1> 匹配=,如果匹配成功,则停止其他匹配 (先进行前缀匹配,再进行正则匹配)
2> 普通字符串的匹配,和其在配置文件中的顺序无关,而是与匹配的长短有关,如果匹配成功的 location 使用了 ^~ ,则停止匹配,否则进行正则匹配(如果正则匹配成功,则使用正则匹配的结果,如果正则匹配不成功,则使用此处匹配的结果) ^~ 若最长前缀匹配含有前面这个字符,则终止后面的正则匹配
3> 正则匹配,按照正则匹配在配置文件中出现的顺序,成功则停止匹配
4> 以上都没匹配成功,则使用 / 通配符匹配
5> 有时候为了避免匹配成功的普通字符串再继续进行正则匹配,会使用 ^~ 符号
6> 在前缀匹配中,寻找并记录最长前缀匹配(两个location,/abc和/abc/def 那么带uri/abc/def/a.jpg的请求匹配的最长前缀就是/abc/def)

顺序 no优先级:
(location =) > (location 完整路径) > (location ^~ 路径) > (location ~ , ~* 正则顺序) > (location 部分起始路径) > (/)

[root@ nginx]# cat nginx.conf
user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
server {
    listen       80;
    server_name  10.252.71.219;

# 精确匹配 / ,主机名后面不能带任何字符串    
    location =/ {                                    #A   
        root   /data/nginxA/;
        index  index.html index.htm;
    }
    
 # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
  # 但是正则和最长字符串会优先匹配	
    location / {                                     #B
        root   /data/nginxB/;
        index  index.html index.htm;
    }

# 匹配任何以 /doc/ 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
    location /doc/ {                                 #C
        root   /data/nginxC/;
        index  index.html index.htm;
    }

# 匹配任何以 /doc/ 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
    location ~ /doc/Abc {                            #D
        root   /data/nginxD/;
        index  index.html index.htm;
    }

 # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
    location ^~ /image/ {                            #E
        root   /data/nginxE/;
        index  index.html index.htm;
    }

# 匹配所有以 gif,jpg或jpeg 结尾的请求 不区分大小写
# 然而,所有请求 /images/ 下的图片会被 config E 处理,因为 ^~ 到达不了这一条正则
    location ~* \.(gif|jpg|jpeg)$ {                  #F
        root   /data/nginxF/;
        index  index.html index.htm;
    }

 # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
 # F与G的放置顺序是没有关系的
    location  /image/abc {                          #G
        root   /data/nginxG/;
        index  index.html index.htm;
    }

# 只有去掉 config E 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
    location ~ /image/abc {                          #H
        root   /data/nginxH/;
        index  index.html index.htm;
    }
}
    include /etc/nginx/conf.d/*.conf;
}

匹配示例

访问根目录http://localhost/ 将匹配规则A
访问 http://localhost/doc 将匹配规则C,http://localhost/file(不是doc) 则匹配规则B
访问 http://localhost/image/a.html 将匹配规则E
访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则F,而 http://localhost/image/c.png 则优先匹配到规则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/
}

示例

普通字符串匹配

location ^~ /helloworld {             #1 
	return 601;
} 

#location /helloworld {               #2 
# 	return 602;
#}

location ~ /helloworld { 
 	return 603;
}

访问http://localhost/helloworld/test,返回601
如果将上面的块注释,中间的块放开注释,则返回603,因为匹配到普通字符串没有带^~,会继续进行正则匹配

普通字符串长短匹配规则

location /helloworld/test/ {
    return 601;
}
        
location /helloworld/ {
    return 602;
}

普通字符串的匹配和配置文件中的顺序无关,而是与匹配的长短有关。

访问http://localhost/helloworld/test/a.html,返回601
http://localhost/helloworld/a.html,返回602

正则匹配和其在配置文件中的顺序有关

location /helloworld/test/ {            #1
return 601;
}

location ~ /helloworld {                #2
return 602;
}

location ~ /helloworld/test {           #3
return 603;
}

访问http://localhost/helloworld/test/a.html,返回602
交换#2和#3调换顺序
访问http://localhost/helloworld/test/a.html,返回603

root和alias的区别

下面这两种写法的区别(html是nginx的默认访问根目录):

location /dir1/ {
	alias html/dir1;
}
location /dir1/ {
	root html/dir1;
}

当访问http://ip/dir1/1.html的时候,如果是第一种配置,则会在html/dir1目录下找1.html文件,
如果是第二种配置,则会在html/dir1/dir1目录下找1.html文件
root是在全目录下继续加上location的路径

proxy_pass 加/和不加/

proxy_pass代理的时候,下面两种写法的区别:

location /proxy/ {
    proxy_pass http://proxy_ip;
}
location /proxy/ {
    proxy_pass http://proxy_ip/;
}

当访问http://ip/proxy/1.html的时候,如果是第一种配置,则代理访问http://proxy_ip/proxy/1.html,
如果是第二种配置,则代理访问http://proxy_ip/1.html