You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx Location匹配算法及请求匹配疑问:为何/tmp/foo.php请求返回Location 3a响应?

Nginx Location匹配算法及请求匹配疑问:为何/tmp/foo.php请求返回Location 3a响应?

嘿,这个问题问得特别精准,刚好戳中了Nginx location匹配里容易被忽略的嵌套location优先级细节!咱们先把你的配置贴出来,对着说更清楚:

location / {
    return 200 "Location 1\n";
}
location ~ \.php$ {
    return 200 "Location 2\n";
}
location /tmp {
    return 200 "Location 3\n";
    location ~ \.php$ {
        return 200 "Location 3a\n";
    }
}

你疑惑的点是:按常规逻辑,外部的~ \.php$(Location 2)应该匹配.php结尾的请求,而且你也知道^~修饰符才会让prefix location跳过regex检查,但这里没加^~,为啥还是走到了内部的3a?

其实核心原因是Nginx的嵌套location是在父prefix location的上下文里优先匹配的,具体流程是这样的:

  • 第一步,Nginx先遍历所有prefix location,计算每个location和请求/tmp/foo.php的匹配长度:/tmp匹配了前4个字符(/tmp),/只匹配1个,所以最长匹配的prefix location是location /tmp。
  • 第二步,这时候Nginx会进入这个location /tmp的块里,然后优先检查块内的嵌套location规则,而不是直接去和外部的regex location做对比。
  • 第三步,你的请求刚好以.php结尾,完美匹配了嵌套的location ~ \.php$,所以直接触发了return 200 "Location 3a\n";,根本轮不到外部的Location 2出场。

简单说就是:当请求匹配到某个prefix location后,Nginx会先在这个location的内部规则里找匹配,内部的规则优先级高于外部的同级规则,和父prefix有没有^~没关系——^~只是用来跳过外部的regex检查,但这里是内部嵌套的regex,本来就属于父location的管辖范围,自然会先被处理。

备注:内容来源于stack exchange,提问作者Ivan Shatsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 11:29:38