Location匹配
匹配类型
| 修饰符 | 含义 | 示例 |
|---|---|---|
= |
精确匹配 | location = /api |
^~ |
前缀匹配,匹配到就停止 | location ^~ /static/ |
~ |
正则匹配(区分大小写) | location ~ \.php$ |
~* |
正则匹配(不区分大小写) | `location ~* .(jpg|gif|png)$ |
| 无 | 普通前缀匹配 | location /api/ |
-
精确匹配
location = /api { #..... } 只有访问是 example.com/api 时才匹配 example.com/api/ ❌ example.com/apis ❌ -
前缀匹配
location ^~ /api/ { #.... } example.com/api/ ✅ example.com/apis ❌ example.com/api/123456 ✅ -
正则匹配
location ~* \.(jpg|gif|png)$ { #\. 是转义 $表示结束 } example.com/avatar.jpg ✅ exampl.com/logo.svg ❌ example.com/logo.pngDoSomeDangerAction ❌ example.com/thepath/logo.png ✅
优先级
高 ┌─────────────────────┐
│ = 精确匹配 │
├─────────────────────┤
│ ^~ 前缀匹配停止 │
├─────────────────────┤
│ ~ 正则(顺序) │
│ ~* 正则(顺序) │
├─────────────────────┤
│ 无 最长前缀匹配 │
低 └─────────────────────┘
拼接规则
root & index
root 表示文件路径地址的根目录, index 表示当发送的请求是目录时会去该目录下查找的文件;
index 指令定义了当用户请求一个目录(而不是一个具体文件)时,Nginx 应该默认返回哪个文件;
location / {
root /var/www/home/;
index index.html index.htm index.php
}
当进入的请求是 example.com/ 时 会匹配到上述 location 匹配段 拆下来 / ,root + / = var/www/home/ 因为查找的是 dir 而非 file ,所以根据 index 从前往后查找 对应文件 / + index [1] = /index.html 重新在 conf 里匹配 。
因为 /index.html 符合 / 的规则,于是 root + /index.html, 此时访问的是具体的文件,检查是否存在然后返回。
alias
alias 常为改善 root 可能导致的 路径重复问题 而使用。
location /images/ {
root /var/www/assets/pics/;
}
我们请求访问时如果是 example.com/images/img.png 到这里会被拆解拼接 为 /var/www/assets/pics/images/img.png
但我们实际只是 暴露给用户的地址是 images 我们的图片路径并不在这里,此时为了保证 API 的易读性和我们后端资源的有序我们可以使用 alias
location /images/ {
alias /var/www/assets/pics/;
}
拼接结果就是 /var/www/assets/pics/img.png
巨坑
使用精准匹配导致 无法托管正确页面
如果我们用精准匹配去设置 根目录为欢迎页,会出错
location =/ {
root /var/www/home/;
index index.html index.htm index.php
}
1977/12/15 15:45:24 [debug] 332923#332923: *17 http request line: "GET / HTTP/1.1"
1977/12/15 15:45:24 [debug] 332923#332923: *17 http uri: "/"
1977/12/15 15:45:24 [debug] 332923#332923: *17 http args: ""
1977/12/15 15:45:24 [debug] 332923#332923: *17 http exten: ""
1977/12/15 15:45:24 [debug] 332923#332923: *17 http header: "Accept: */*"
1977/12/15 15:45:24 [debug] 332923#332923: *17 http header done
1977/12/15 15:45:24 [debug] 332923#332923: *17 test location: "/avatar/"
1977/12/15 15:45:24 [debug] 332923#332923: *17 test location: "/404.html"
1977/12/15 15:45:24 [debug] 332923#332923: *17 test location: "/"
1977/12/15 15:45:24 [debug] 332923#332923: *17 using configuration "=/" #使用“=/精准匹配”
1977/12/15 15:45:24 [debug] 332923#332923: *17 open index "/var/www/home/index.html" #检查index.html是否存在
1977/12/15 15:45:24 [debug] 332923#332923: *17 internal redirect: "/index.html?" #内部重定向
1977/12/15 15:45:24 [debug] 332923#332923: *17 rewrite phase: 1
1977/12/15 15:45:24 [debug] 332923#332923: *17 test location: "/avatar/"
1977/12/15 15:45:24 [debug] 332923#332923: *17 test location: "/static/"
1977/12/15 15:45:24 [debug] 332923#332923: *17 test location: "/health" #找不到了因为 /index.html 不匹配 /
1977/12/15 15:45:24 [error] 332923#332923: *17 open() "/etc/nginx/html/index.html" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost:8070"
1977/12/15 15:45:24 [debug] 332923#332923: *17 http finalize request: 404, "/index.html?" a:1, c:2
1977/12/15 15:45:24 [debug] 332923#332923: *17 http special response: 404, "/index.html?"
1977/12/15 15:45:24 [debug] 332923#332923: *17 internal redirect: "/404.html?"
1977/12/15 15:45:24 [debug] 332923#332923: *17 rewrite phase: 1
1977/12/15 15:45:24 [debug] 332923#332923: *17 test location: "/avatar/"
1977/12/15 15:45:24 [debug] 332923#332923: *17 test location: "/404.html"
1977/12/15 15:45:24 [debug] 332923#332923: *17 using configuration "=/404.html"
解决方案
-
使用 try_files
try_files 检查文件是否按指定顺序存在,并使用 第一个用于请求处理的寻得文件; 处理过程 在当前语境下执行。
Checks the existence of files in the specified order and uses the first found file for request processing;
这样就避免了内部重定向
location =/ { root /var/www/home/; try_files /index.html =404 } -
将 root 放在全局
admin/ 与 admin 同时跳转同一 index
location /admin {
alias /var/www/admin/;
index index.html;
try_files $uri $uri/index.html =404;
}
Reference
title: "Nginx基础知识从小白到入门"
image: "https://raw.githubusercontent.com/wsgzao/storage-public/master/img/20191113180648.png"
description: "Nginx基础知识从小白到入门"
url: "https://wsgzao.github.io/post/nginx/"
favicon: ""
aspectRatio: "96.79245283018868"
title: "Nginx 快速教程"
image: "https://raw.githubusercontent.com/dunwu/images/master/cs/web/nginx/nginx.jpg"
description: "nginx-tutorial"
url: "https://dunwu.github.io/nginx-tutorial/#/nginx-quickstart"
favicon: ""
aspectRatio: "56.26959247648903"
title: "Nginx 从入门到实践(2023年版)Nginx 简介 Nginx 是什么 nginx (engine x) 是一个 - 掘金"
image: "https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/75209bc63f284481ae19c0c98d41187e~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp?"
description: "Nginx 简介 Nginx 是什么 nginx (engine x) 是一个 HTTP 和反向代理服务器,一个邮件代理服务器,一个通用的 TCP/UDP 代理服务器,最初由 Igor Sysoev "
url: "https://juejin.cn/post/7223653286464667703#heading-20"
favicon: ""
aspectRatio: "96.18268575323789"
title: "try_files 文档"
image: "https://nginx.org/img/nginx_logo.svg"
description: ""
url: "https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files"
favicon: ""
aspectRatio: "28.666666666666668"
title: "index 文档"
image: "https://nginx.org/img/nginx_logo.svg"
description: ""
url: "https://nginx.org/en/docs/http/ngx_http_index_module.html#index"
favicon: ""
aspectRatio: "28.666666666666668"