一、基本概念

location 块用于在 Nginx 配置文件中定义一个位置匹配规则。当客户端发送请求时,Nginx 会根据请求的 URI 来匹配 location 块,并执行相应的处理指令。location 块可以嵌套在 server 块中,也可以嵌套在其他 location 块中。
参考:[[https://mp.weixin.qq.com/s?__biz=Mzg4ODQ1NTE2Mg==&mid=2247564585&idx=1&sn=29e7629cabec57b0596d1a345e780d5e&chksm=ce03fc8010225a52dc1c9063d59b8947f4bba6d0cee50a1b5f19f74493a2cd1e5513d35b66ef&scene=27|# 深入理解 Nginx Location 块:配置示例与应用场景详解]]

二、location 块的语法

1
2
3
location [修饰符]  <匹配模式> {
# 处理指令
}

1.修饰符(可选)

  • 路径匹配:
    = 开头表示精确匹配。如 A 中只匹配根目录结尾的请求,后面不能带任何字符串;
    ^~ 开头表示uri以某个常规字符串开头,不是正则匹配;
    ~ 开头表示区分大小写的正则匹配;
    ~* 开头表示不区分大小写的正则匹配;
    / 通用匹配, 如果没有其它匹配,任何请求都会匹配到。
  • 匹配优先级:
    ( location = ) > ( location 完整路径 ) > ( location ^~ 路径 ) > ( location ,* 正则顺序 ) > ( location 部分起始路径 ) > ( / )

2.匹配模式

用于匹配请求 URI 的字符串或正则表达式。

3.处理指令

3.1 root(推荐) 和 alias:设置请求文件的基本目录。
详解:[[https://www.jb51.net/server/32545404c.htm]]
location /i/ {…} ;请求地址:http://xxx.net/i/k/top.gif

  • root /var/www/html; 文件绝对路径=root+location,即:/var/www/html/i/k/top.gif
  • alias /var/www/static/; 必须以"/"结尾,文件绝对路径=alias+去掉location的文件路径,即:/var/www/html/k/top.gif
    3.2 proxy_pass:将请求代理到后端服务器。
    用 http://192.168.1.1/proxy/test.html 访问请求,示例说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
第一种:location /proxy/ {
   proxy_pass http://127.0.0.1/;
}
代理到URLhttp://127.0.0.1/test.html

第二种(相对于第一种,最后少一个 / )
location /proxy/ {
   proxy_pass http://127.0.0.1;
}
代理到URLhttp://127.0.0.1/proxy/test.html

第三种:location /proxy/ {
   proxy_pass http://127.0.0.1/aaa/;
}
代理到URLhttp://127.0.0.1/aaa/test.html

第四种(相对于第三种,最后少一个 / )
location /proxy/ {
   proxy_pass http://127.0.0.1/aaa;
}
代理到URLhttp://127.0.0.1/aaa/proxy/test.html

2.rewrite:重写请求的 URI。
3.try_files:尝试不同的文件或路径,直到找到一个存在的。

5.index:指定目录索引文件。
6.autoindex:启用或禁用目录列表。
7.error_page:定义错误页面。
8.auth_basic 和 auth_basic_user_file:设置 HTTP 基本认证。

三、示例配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 处理根路径
location = / {
index index.html;
}

# 处理静态资源
location /static/ {
alias /var/www/static/;
}

location ^~ /static/ {
   root /webroot/static/;
}

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
   root /webroot/res/;
}

# 代理到后端应用服务器
location /api/ {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

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

# 自定义错误页面
error_page 404 /404.html;
location = /404.html {
root /var/www/html;
internal;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1、用前缀字符串(前缀location)匹配URL,并且选中并记住最长匹配前缀的location(注意:是在匹配的里面记住最长的那个)

2、按照正则表达式在配置文件中出现的顺序依次去匹配,当匹配到第一个以后立即停止,并使用与之相应的那个location。如果没有一个正则表达式匹配,则使用之前记住的那个前缀location。

以上,我们可以得出一个结论:优先使用正则表达式,如果没有匹配的正则表达式发现,则使用匹配的最长前缀字符串location

```javascript
location  = / {
 # 精确匹配 / ,主机名后面不能带任何字符串
 [ configuration A ]
}
location  / {
 # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
 # 但是正则和最长字符串会优先匹配
 [ configuration B ]
}
location /documents/ {  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
 [ configuration C ]
}
location ~ /documents/Abc {  # 匹配任何以 /documents/Abc 开头的地址,匹配符合以后,还要继续往下搜索
 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
 [ configuration CC ]
}
location ^~ /images/ {  # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
 [ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {  # 匹配所有以 gif,jpg或jpeg 结尾的请求
 # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
 [ configuration E ]
}
location /images/ {  # 字符匹配到 /images/,继续往下,会发现 ^~ 存在
 [ configuration F ]
}
location /images/abc {  # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
 # F与G的放置顺序是没有关系的
 [ configuration G ]
}
location ~ /images/abc/ {  # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
 # 因为都是正则匹配,优先级一样,选择最上面的
   [ configuration H ]
}
location ~* /js/.*/\.js