# Nginx教程 - 9 location配置

在 Nginx 中,location 配置块用于匹配 URI(统一资源标识符)并定义处理这些请求的方法。location 指令通常出现在 server 块中,用于根据不同的 URI 对请求进行分类和处理。 location 是可以配置多个的,而且可以根据不同的匹配规则来匹配和处理不同的请求。


# 9.1 基本语法

location [modifier] pattern {
    # 配置指令
}
1
2
3

Modifiers 表示修饰符,下面依次介绍一下常用的修饰符:

  • =:精确匹配。例如,location = /abc 仅匹配根请求 /abc
  • ^~ :前缀匹配。用于匹配一个 URI 前缀,并在找到匹配时立即停止进一步搜索。例如,location ^~ /images/ 匹配以 /images/ 开头的请求。
  • ~ :区分大小写的正则表达式匹配。例如,location ~ \.jpg$ 匹配所有以 .jpg 结尾的请求。
  • ~* :不区分大小写的正则表达式匹配。例如,location ~* \.jpg$ 匹配所有以 .jpg 结尾的请求,不论大小写。
  • !~ :表示区分大小写不匹配的正则表达式匹配(较少用)。
  • !~* :表示不区分大小写不匹配的正则表达式匹配(较少用)。
  • 无修饰符:普通前缀匹配,如果没有其他更精确的匹配,这个块将被使用,例如之前使用的 location /location /abc

# 9.2 匹配规则

# 1 精确匹配 ( = )

  • 精确匹配的优先级最高,一旦匹配成功,则不再查找其他 location 的匹配项。

# 2 前缀匹配

  • Nginx 会首先尝试找到最长的前缀匹配(包括带 ^~ 修饰符 和 无修饰符)。

  • 如果找到的最长前缀匹配是带 ^~ 修饰符的,则匹配结束,使用该 location 块。

  • 如果找到的最长前缀匹配是无修饰符的,则继续进行正则表达式匹配。

  • 如果找到多个最长前缀匹配,则优先匹配带 ^~ 修饰符的。

# 3 正则表达式匹配

  • 正则表达式匹配按照顺序匹配一个,只要有一个正则表达式匹配成功,则使用该 location 块,并立即返回结果,结束解析过程。
  • 如果没有任何正则表达式匹配成功,则使用最长的无修饰符的前缀匹配 location 块。

# 9.3 匹配举栗子

# 1 精确匹配 (=)

server {
    listen 80;
    server_name localhost;

    location = / {
        add_header Content-Type text/plain;  # 提示浏览器返回的是纯文本,否则浏览器可能会提示下载
        return 200 "request: /";
    }
  
    location /test {
        add_header Content-Type text/plain;
        return 200 "request: /test";
    }

    location = /test {
        add_header Content-Type text/plain;
        return 200 "request: =/test";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • 请求 /:匹配 location = /,返回 request: /
  • 请求 /test:精确匹配 location = /test,返回 request: =/test

# 2 前缀匹配(^~ 和 无修饰符)

server {
    listen 80;
    server_name www.doubibiji.com;

    location ^~ /test/ {
        add_header Content-Type text/plain;
        return 200 "request: ^~ /test/";
    }
  
    location ^~ /test/abc/ {
        add_header Content-Type text/plain;
        return 200 "request: ^~ /test/abc/";
    }
  
    location /test/ {
        add_header Content-Type text/plain;
        return 200 "request: /test/";
    }
  
    location /test/bcd/ {
        add_header Content-Type text/plain;
        return 200 "request: /test/bcd/";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  • 请求 /test/xyz:匹配 location ^~ /test/,优先级比 location /test/ 高,返回 request: ^~ /test/
  • 请求 /test/abc/xyz:匹配到最长的 location ^~ /test/abc/,返回 request: ^~ /test/abc/
  • 请求 /test/bcd/xyz:匹配到最长的 location /test/bcd/,返回 request: /test/bcd/

# 3 正则表达式匹配(~~*

server {
    listen 80;
    server_name www.doubibiji.com;

    location ^~ /test/ {
        add_header Content-Type text/plain;
        return 200 "request: ^~ /test/";
    }
  
    location /test/abc/ {
        add_header Content-Type text/plain;
        return 200 "request: /test/abc/";
    }
  
    location ~ /test/ {
        add_header Content-Type text/plain;
        return 200 "request: ~ /test/";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • 请求 /test/xyz:最长的匹配是 location ^~ /test/,返回 request: ^~ /test/
  • 请求 /test/abc/xyz:最长的匹配时 location /test/abc/,是无符号匹配,则进行正则匹配,匹配到 location ~ /test/,返回 request: ~ /test/

使用正则表达式比较灵活,可以进行后缀匹配:

location ~* \.(jpg|jpeg|png|gif|ico)$ { # 匹配任何以gif、jpg、jpeg等结尾的文件
    root /var/www;
} 
1
2
3

# 9.4 root和alias

# 1 root

root 指令指定一个目录作为根目录,匹配到的URI会相对于这个根目录来解析。

location /static/ {
    root /var/www;
}
1
2
3

当请求URL为/static/abc/pic.jpg时,会匹配到 location /static/ ,会将 /static/ 包括其后的内容拼接到 /var/www 后面,所以 /var/www 后面不能有 / 了,最终得到映射到文件系统中的路径:/var/www/static/abc/pic.jpg

# 2 alias

alias指令也是用于指定文件系统路径,但它直接将请求的URI映射到指定的目录,不再考虑location的URI部分。

location /static/ {
    alias /var/www/;  # 结尾需要有/,因为会将/static/之后的内容拼接在后面,而/static/之后的内容没有/了
}
# 或者
location /static {
    alias /var/www;  # 这样结尾没有/,也就是说如果location路径是以/结尾,则alias也必须是以/结尾
}
1
2
3
4
5
6
7

当请求URL为/static/abc/pic.jpg时,Nginx会将其映射到文件系统路径/var/www/abc/pic.jpg


rootalias 的区别:

root 会将location中的URI部分保留并与root指令指定的路径拼接。

alias 则会直接用指定的路径替换location中的URI部分。