nginx 中 location 优先级的问题

190 天前
 Hopetree

我有一份配置:

server {
    listen 12080;
    server_name abc.com;

    access_log  /var/log/nginx/test.access.log;
    error_log   /var/log/nginx/test.error.log;

    location ~* \.png$ {
        return 402;
    }

    location / {
        return 400;
    }

    location /static/js/css/ {
        return 405;
    }

    location ^~ /static/ {
        return 401;
    }

    location ^~ /static/js/ {
        return 404;
    }

    location = /static/abc.png {
        return 403;
    }
}

为什么/static/js/css/4.png 返回 402 ,而/static/js/4.png 返回 404 ?正则的优先级不是很低吗,第一个为什么是正则生效,并且/static/js/css6/4.png 又是 404 ,第一个地址和第 3 个地址为什么会出现不同的匹配生效?

2444 次点击
所在节点    NGINX
30 条回复
TommySung
190 天前
是没问题的!

毫无疑问,匹配原则是精确匹配,即最大程度能匹配上

在这一原则下,最长匹配就是判断标准

1.
首先 /static/js/css/4.png 会匹配到 1 ,保留
然后,/static/js/css/4.png 会匹配到 3 ,而 4 ,5 ,6 都无法与其”匹敌“,因为 3 和他们比较匹配度最高
而 1 因为是正则匹配,且能匹配到结尾扩展名,也属于匹配度最高,换句话说你使用/static/js/css/4.jpg 则会匹配到 3

在此情况下,1 和 3 匹配度都最高,那么正则优先,所以 /static/js/css/4.png 会匹配到 1


2.
/static/js/4.png 最高匹配度会匹配到 1 ,3 ,5 ,但 5 的优先级明显高于 1 和 3 ,所以返回 5

3.
/static/js/css6/4.png 同上

容易错误的地方如:
location /static/js/css/
location ^~ /static/js/
如果你的 uri 包括/static/js/css/ ,那么虽然 location ^~ /static/js/ 也能匹配上,并且优先级高于 location /static/js/css/
但 location /static/js/css/ 属于最精确匹配或最高匹配度,最后就会被选中

匹配度最高或最精准匹配 是 大于 所谓优先级的
godall
190 天前
@rockyliang 大师
Leon406
190 天前

凑个热闹
Hopetree
190 天前
@Leon406 怎么解释这个图,有相关文章说明的吗,有的话麻烦推一下,我看了好多文章,但是把我测试的配置和请求结果拿去验证发现没有有个经得住验证的
omgr
190 天前
官方文档写的很清楚了,细读下就好了。

> If the longest matching prefix location has the “^~” modifier then regular expressions are not checked

你给的测试网址也说明了这个问题,prefix 匹配实际上分两种,如果最长匹配命中的是 ^~ 类型的,就会直接返回,如果是普通的,同时有正则的话,就会按写的顺序依次正则匹配,正则匹配到了就用正则了。

你的例子中:
/static/js/css/4.png 最长前缀匹配到了 /static/js/css/ 会继续检查正则
/static/js/4.png 最长前缀匹配到了 ^~ /static/js/ 直接返回
omgr
190 天前
跟 405 状态码没有关系的
Hopetree
189 天前
经过上面 21 和 25 楼的解析,我画了一个流程图,不知道按照验证好像是对的,请各位大佬看看,是不是这样
![image]( https://github.com/Hopetree/izone/assets/30201215/fa522cfe-9e5a-453b-b2f6-2f89b9250596)
Hopetree
189 天前
重新编辑一下:经过上面 21 和 25 楼的解析,我画了一个流程图,按照验证好像是对的,请各位大佬看看,是不是这样

![image]( https://github.com/Hopetree/izone/assets/30201215/fa522cfe-9e5a-453b-b2f6-2f89b9250596)
Hopetree
189 天前
Hopetree
185 天前
我为这个讨论的结果写了一篇学习总结文章,有兴趣的可以看看,https://tendcode.com/subject/article/nginx-location/,如果文章中表述有错误的,欢迎指出纠正

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1002226

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX