Nginx之location配置

文章目录

匹配规则

符号 规则说明
= 进行普通字符精确匹配,也就是完全匹配
^~ 表示普通字符匹配,使用前缀匹配,如果匹配成功,则不再匹配其它 location。
~ 区分大小写的匹配
~* 不区分大小写的匹配
!~ 区分大小写的匹配取非,!表示取反
!~* 不区分大小写的匹配取非。
@ 定义一个命名的location,使用在内部定向时
  • 普通匹配:location /xxx {},匹配所有以/xxx开头的url
  • 默认匹配:location / {},前缀匹配的特殊情况,匹配所有的url
  • 精准匹配:location = /xxx {},精确匹配,只有url为/xxx时,才会匹配,/xx、/xxx/abc 都不匹配
  • 正则匹配:location ~ /xxx {},正则匹配,可以使用正则表达式规则匹配

肯定会有善于思考的朋友会问,那我同时有多个location都匹配,怎么办?

所以,有最长匹配原则和匹配优先级规则。

关于最长匹配原则很好理解,一个简单的例子。

我们有如下配置,那么我们访问http://localhost:7000/docs/abc,会走到哪一个location呢?

url会对于2个location:location /docs/abc,location /docs都匹配,那么会选择最长匹配。

conf 复制代码
worker_processes  1;

events {
    worker_connections  1024;
}

http {

    server {
        listen       7000;
        server_name  localhost;
        charset utf-8;
        location /docs/abc {
            default_type application/json;
            return 200 '{"code":200,"location":"/docs/abc"}';
        }

        location /docs {
            default_type application/json;
            return 200 '{"code":200,"location":"/docs"}';
        }
    }
}

现在是不是就理解为什么location / 叫默认匹配了,因为它能匹配所有的url,但是它是最短的,所以只有其他location都没有匹配上的时候,才能匹配到它。

conf 复制代码
location / {
    root   html;
    index  index.html index.htm;
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET,POST,DELETE';
    add_header 'Access-Control-Allow-Header' 'Content-Type,*';
}

匹配优先级

最长匹配那是针对同一规则下的匹配,如果不同规则,应该怎样匹配呢?

例如,我们nginx配置如下:

conf 复制代码
worker_processes  1;

events {
    worker_connections  1024;
}

http {

    server {
        listen       7000;
        server_name  localhost;
        charset utf-8;
        
        location /img/abc/xxx {
            default_type application/json;
            return 200 '{"code":200,"location":"/img/abc/xxx"}';
        }

        location ~ /img/abc/xxx {
            default_type application/json;
            return 200 '{"code":200,"location":"~ /img/abc/xxx"}';
        }

        location ~ /img/abc {
            default_type application/json;
            return 200 '{"code":200,"location":"~ /img/abc"}';
        }

        location ^~ /img/abc {
            default_type application/json;
            return 200 '{"code":200,"location":"^~ /img/abc"}';
        }

        location /img/abc/xxx/zzz {
            default_type application/json;
            return 200 '{"code":200,"location":"/img/abc/xxx/zzz"}';
        }
    }
}

下面3个url分别会匹配哪个location呢?

http://localhost:7000/img/abc/xxx/zzz

http://localhost:7000/img/abc/xxx

http://localhost:7000/img/abc

所以,对于不同规则都能匹配的情况,还需要一个优先级规则。

优先级从高到低排列:

  1. 精确匹配 =(location = /abc)
  2. 前缀匹配 ^~ (location ^~ /abc)
  3. 顺序的正则匹配 * (location ~ /abc)
  4. 普通前缀匹配(location /abc)
  5. 通用匹配(location /)

注意:优先级规则,先于最长匹配规则。

现在,我们对于前面的问题就有答案了:

http://localhost:7000/img/abc/xxx/zzz:匹配location ~ /img/abc/xxx,没有匹配更长的location /img/abc/xxx/zzz,是因为正则匹配优先级,比普通匹配优先级更高。

http://localhost:7000/img/abc/xxx:毫无疑问,匹配location ~ /img/abc/xxx

http://localhost:7000/img/abc:匹配\^\~ /img/abc,因为前缀匹配优先级比普通正则匹配~ /img/abc优先级更高。

location匹配示例

前缀匹配

conf 复制代码
worker_processes  1;

events {
    worker_connections  1024;
}

http {

    server {
        listen       7000;
        server_name  localhost;
        charset utf-8;
        
        location ^~ /img/ {
            default_type application/json;
            return 200 '{"code":200,"location":"^~ /img/"}';
        }
    }
}

后缀匹配

conf 复制代码
worker_processes  1;

events {
    worker_connections  1024;
}

http {

    server {
        listen       7000;
        server_name  localhost;
        charset utf-8;

        location ~* \.(gif|jpg|jpeg)$ {
            default_type application/json;
            return 200 '{"code":200,"location":"后缀匹配"}';
        }
    }
}

@符号

conf 复制代码
worker_processes  1;

events {
    worker_connections  1024;
}

http {

    server {
        listen       7000;
        server_name  localhost;
        charset utf-8;

        location = /401 {
            return 401;
        }

        location = /403 {
            return 403;
        }

        location = /429 {
            return 429;
        }

        error_page 401 = @unauthorized;
        error_page 403 = @forbidden;
        error_page 429 = @authfail;

        location @unauthorized {
            default_type application/json;
            return 401 '{"code":401,"message":"未授权:token无效或过期","location":"@unauthorized"}';
        }

        location @forbidden {
            default_type application/json;
            return 403 '{"code":403,"message":"禁止访问:无该接口权限","location":"@forbidden"}';
        }

        location @authfail {
            default_type application/json;
            return 429 '{"code":429,"message":"访问太频繁","location":"@authfail"}';
        }
    }
}

http://localhost:7000/401

http://localhost:7000/403

http://localhost:7000/429

正则表达式元字符说明表

元字符 功能说明 示例
^ 匹配输入字符串的起始位置 -
$ 匹配输入字符串的结束位置 -
* 匹配前面的字符零次或多次 go* 能匹配 ggogoogooo
+ 匹配前面的字符一次或多次 go+ 能匹配 gogo0gooo,不能匹配 g
? 匹配前面的字符零次或一次,等效于 {0,1} go? 能匹配 g 或者 go
. 匹配除 \n 之外的任何单个字符 匹配包括 \n 在内的任意字符可使用 [.\n]
\ 转义字符 \n 匹配换行符,\$ 匹配 $
\d 匹配纯数字 [0123456789]
{n} 重复匹配前面的表达式 n 次 \d{11}匹配11位数字,简单验证手机号
{n,} 重复匹配前面的表达式 n 次或更多次 \d{6,} 匹配6位及以上数字
{n,m} 重复匹配前面的表达式 n 到 m 次 \d{6,12} 匹配6-12位数字
[] 定义匹配的字符范围 [0-9] 匹配0-9中的任意一个数字,[c] 匹配单个字符 c
[] 定义匹配的字符范围 [a-z]匹配 a-z 小写字母中的任意一个 -
[] 定义匹配的字符范围 [a-zA-Z0-9]匹配所有大小写字母或数字 -
() 标记表达式的开始和结束位置,用于分组 -
` ` 或运算符,匹配多个表达式中的任意一个
相关推荐
十六年开源服务商2 小时前
WordPress定制开发最佳公司的用户画像
运维
世岩清上3 小时前
AI驱动的智能运维:从自动化到自主化的技术演进与架构革新
运维·人工智能·自动化
张童瑶4 小时前
Linux SSH隧道代理转发及多层转发
linux·运维·ssh
石小千4 小时前
Linux安装OpenProject
linux·运维
Lime-30904 小时前
制作Ubuntu 24.04-GPU服务器测试系统盘
linux·运维·ubuntu
代码or搬砖4 小时前
Nginx详讲
运维·nginx·dubbo
守城小轩4 小时前
基于Chrome140的Quora账号自动化——运行脚本(三)
运维·自动化·chrome devtools·指纹浏览器·浏览器开发
百年渔翁_肯肯4 小时前
Linux 与 Unix 的核心区别(清晰对比版)
linux·运维·unix
胡闹545 小时前
Linux查询防火墙放过的端口并额外增加需要通过的端口命令
linux·运维·windows