nginx的location匹配顺序是怎么样的?

我的nginx的location配置如下:

server {
    listen 80;

    root /home/vagrant/www/test/public;

    index index.html index.htm index.nginx-debian.html index.php;

    server_name www.test.cc;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }
}

现在我的项目可以正常的访问的。我就想问一下,比如我访问一个地址:www.test.cc/callback/test

class CallBackController extends Controller
{
    public function test()
    {
       echo 999;
    }
}

他会正常打印999
那么这个地址他会匹配到哪个location?还是两个location都会匹配到?
之前一直以为只是匹配location ~ .php$这个的,我特意把location /这块全部去掉,运行上面地址,直接报404 Not Found

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 14
Mutoulee

location / {} 优先级最低的吧

2年前 评论
bluememory (楼主) 2年前
Mutoulee (作者) 2年前
bluememory (楼主) 2年前

先 普通匹配 ,在正则 匹配,精准匹配最高

其中“普通 location ”是以“ = ”或“ ^~ ”为前缀或者没有任何前缀的 /uri/ ;

正则 location ”是以“ ~ ”或“ ~* ”为前缀的 /uri/ 。

~ 大小写不敏感

~* 大小写敏感

= 则表达的是普通 location 不允许“最大前缀”匹配结果,必须严格等于,严格精确匹配。

^~ 的意思是“非正则,不需要继续正则匹配”

文章中都是正则配置 所以按编辑顺序逐个匹配(与顺序有关),只要匹配上(最大前缀匹配),就立即停止后面的搜索。

2年前 评论
bluememory (楼主) 2年前
zzzzzzz- (作者) 2年前

tengine.taobao.org/nginx_docs/cn/do...

可以使用前缀字符串或者正则表达式定义路径。

这是前缀字符串

location / {

}

这是正则

使用正则表达式需要在路径开始添加“~*”前缀 (不区分大小写),或者“~”前缀(区分大小写)。

location ~ \.php$ {

 }

第一次匹配

匹配的URI是 /callback/test
1

为了根据请求URI查找路径,nginx先检查前缀字符串定义的路径 (前缀路径),在这些路径中找到能最精确匹配请求URI的路径。

没有精确匹配的前缀路径 location /callback/test {}

2

然后nginx按在配置文件中的出现顺序检查正则表达式路径, 匹配上某个路径后即停止匹配并使用该路径的配置

也没有匹配到正则

3

否则使用最大前缀匹配的路径的配置。

最大前缀是指 /callback/test > /callback > /
于是 /callback/test 匹配的是 /

/callback/test 在第一次匹配中匹配到了 /$uri $uri/ 自然是没有对应的文件(index.html) try_files 走到最后的 /index.php?$query_string,然后第二次匹配

第二次匹配

匹配的URI 是/index.php?$query_string

先匹配到了 /

location / {

}

再匹配正则,匹配到了正则会覆盖前缀匹配,因此最终匹配到了这个指令块

..检查正则表达式路径, 匹配上某个路径后即停止匹配..

location ~ \.php$ {

}

仔细的读一下文档中的这段

nginx先检查前缀字符串定义的路径 (前缀路径),在这些路径中找到能最精确匹配请求URI的路径。然后nginx按在配置文件中的出现顺序检查正则表达式路径, 匹配上某个路径后即停止匹配并使用该路径的配置,否则使用最大前缀匹配的路径的配置。

2年前 评论
php_yt (作者) 2年前
bluememory (楼主) 2年前

这么简单的问题就不能去看看文档吗,非要在这人发帖问,简直是舍近求远!nginx.org/en/docs/http/request_proc...

2年前 评论
bluememory (楼主) 2年前

问题2

...
root /home/vagrant/www/test/public;
...
location / {        # 2、通用匹配,优先级最低
    try_files $uri $uri/ /index.php?$query_string;  # 定义 3个规则,先从 $uri 查找,再从 $uri/ 目录中查找,最后 /index.php?$query_string
}

location ~ \.php$ { # 1、正则匹配
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}

你请求 www.test.cc/callback/test 会依次

  1. 先匹配 “正则匹配” 没有,继续向下
  2. 匹配到 /
  3. 进入到 try_files 指令,你定义了 3 个规则
  4. 查找/home/vagrant/www/test/public/callback/test 没有,继续向下
  5. 查找 /home/vagrant/www/test/public/callback/test/ 没有,继续向下
  6. 请求 www.test.cc/index.php?$query_string 同时匹配到 “正则匹配” 走到 fastcgi ...
  7. 解析 www.test.cc/callback/test 并响应
  8. 然后就输出 999 了

问题2:所以你删除 我特意把 location / 这块全部去掉 肯定不行呗,PHP 找谁去!!!

问题1

问题1:2个都要匹配到的

优先级

不同层的优先级

  • 内层块中的指令 > 外层块中的指令

同层的优先级

  • 首先:精确匹配 =若成功,则停止后面的步骤,若没有,继续下面的步骤
  • 其次:前缀匹配 ^~ 最长匹配
  • 其次:是按文件中顺序的正则匹配 ~~*
  • 然后:是匹配不带任何修饰的前缀匹配
  • 最后:是交给 / 通用匹配

其他的就看官方了!!!


瞎猜,别喷,我也是新手...也不知道对不对,探讨探讨~ :stuck_out_tongue_closed_eyes:

2年前 评论
bluememory (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!