嗨客网搜索

Nginx location配置

Nginx location教程

Nginx 中的 location 指令是 nginx 中最关键的指令之一,location 指令的功能是用来匹配不同的 URI 请求,进而对请求做不同的处理和响应,这其中较难理解的是多个 location 的匹配顺序。

开始之前先明确一些约定,我们输入的网址叫做请求 URI,nginx 用请求 URI 与 location 中配置的 URI 做匹配。

location配置

语法

location [ = | ~ | ~* | ^~ ] /URI { … } location @/name/ { … }

使用环境

server

说明

Location 块通过指定模式来与客户端请求的 URI 相匹配。匹配 URI 类型,有四种参数可选,当然也可以不带参数。

命名 location,用 @ 来标识,类似于定义 goto 语句块。

命令解释

参数 解释
location 后没有参数直接跟着标准 URI,表示前缀匹配,代表跟请求中的 URI 从头开始匹配。
= 用于标准 URI 前,要求请求字符串与其精准匹配,成功则立即处理,nginx 停止搜索其他匹配。
^~ 用于标准 URI 前,并要求一旦匹配到就会立即处理,不再去匹配其他的那些个正则 URI,一般用来匹配目录
~ 用于正则 URI 前,表示 URI 包含正则表达式, 区分大小写
~* 用于正则 URI 前, 表示 URI 包含正则表达式, 不区分大小写
@ @ 定义一个命名的 location,@ 定义的 locaiton 名字一般用在内部定向,例如 error_page, try_files 命令中。它的功能类似于编程中的 goto。

匹配规则说明

模式 含义
location = /uri = 表示精确匹配,只有完全匹配上才能生效
location ^~ /uri ^~ 开头对 URL 路径进行前缀匹配,并且在正则之前
location ~ pattern 开头表示区分大小写的正则匹配
location ~* pattern 开头表示不区分大小写的正则匹配
location /uri 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后
location / 通用匹配,任何未匹配到其它 location 的请求都会匹配到,相当于 switch 中的 default

Nginx location匹配顺序

Nginx 有两层指令来匹配请求 URI 。第一个层次是 server 指令,它通过域名、ip 和端口来做第一层级匹配,当找到匹配的 server 后就进入此 server 的 location 匹配。

location 的匹配并不完全按照其在配置文件中出现的顺序来匹配,请求URI 会按如下规则进行匹配:

  1. 先精准匹配 = ,精准匹配成功则会立即停止其他类型匹配;
  2. 没有精准匹配成功时,进行前缀匹配。先查找带有 ^~ 的前缀匹配,带有 ^~ 的前缀匹配成功则立即停止其他类型匹配,普通前缀匹配(不带参数 ^~ )成功则会暂存,继续查找正则匹配;
  3. = 和 ^~ 均未匹配成功前提下,查找正则匹配 ~ 和 ~* 。当同时有多个正则匹配时,按其在配置文件中出现的先后顺序优先匹配,命中则立即停止其他类型匹配;
  4. 所有正则匹配均未成功时,返回步骤 2 中暂存的普通前缀匹配(不带参数 ^~ )结果。

以上规则简单总结就是优先级从高到低依次为(序号越小优先级越高):

1. location = # 精准匹配 2. location ^~ # 带参前缀匹配 3. location ~ # 正则匹配(区分大小写) 4. location ~* # 正则匹配(不区分大小写) 5. location /a # 普通前缀匹配,优先级低于带参数前缀匹配。 6. location / # 任何没有匹配成功的,都会匹配这里处理

location URI结尾带不带/

关于 URI 尾部的 / 有三点也需要说明一下。第一点与 location 配置有关,其他两点无关。

  1. location 中的字符有没有 / 都没有影响。也就是说 /user//user 是一样的。
  2. 如果 URI 结构是 https://domain.com/ 的形式,尾部有没有 / 都不会造成重定向。因为浏览器在发起请求的时候,默认加上了 / 。虽然很多浏览器在地址栏里也不会显示 /
  3. 如果 URI 的结构是 https://domain.com/some-dir/ 。尾部如果缺少 / 将导致重定向。因为根据约定,URL 尾部的 / 表示目录,没有 / 表示文件。所以访问 /some-dir/ 时,服务器会自动去该目录下找对应的默认文件。如果访问 /some-dir 的话,服务器会先去找 some-dir 文件,找不到的话会将 some-dir 当成目录,重定向到 /some-dir/ ,去该目录下找默认文件。可以去测试一下你的网站是不是这样的。

命名location

带有 @ 的 location 是用来定义一个命名的 location,这种 location 不参与请求匹配,一般用在内部定向。用法如下:

location / { try_files $uri $uri/ @custom } location @custom { # ...do something }

上例中,当尝试访问 URI 找不到对应的文件就重定向到我们自定义的命名 location(此处为 custom)。值得注意的是,命名 location 中不能再嵌套其它的命名 location。

案例

案例一

我们首选使用 vim 打开 nginx 的默认配置路径,具体命令如下:

vim /etc/nginx/conf.d/default.conf

我们执行如上命令,打开配置文件,接着,我们在 server 下面增加两个 location 配置,具体配置如下:

location /doc { return 701; # 用这样的方式,可以方便的知道请求到了哪里 } location ~* ^/document$ { return 702; }

配置完毕后,如下图所示:

38_nginx location配置.png

现在,我们重新加载配置文件,具体命令如下:

nginx -s reload

重新加载配置后,我们使用 curl 测试,具体命令如下:

curl -I 127.0.0.1/document

执行完毕后,终端输出如下:

39_nginx location配置.png

即,这里,优先匹配了下面的 document 配置。

案例二

我们在 Nginx 的 server 下面增加两个 location 配置,具体配置如下:

location /document { return 701;}location ~* ^/document$ { return 702;}

配置完毕后,如下图所示:

40_nginx location配置.png

现在,我们重新加载配置文件,具体命令如下:

nginx -s reload

重新加载配置后,我们使用 curl 测试,具体命令如下:

curl -I 127.0.0.1/document

执行完毕后,终端输出如下:

41_nginx location配置.png

即,这里,优先匹配了下面的 document 配置。

案例三

我们在 Nginx 的 server 下面增加两个 location 配置,具体配置如下:

location ^~ /doc { return 701;}location ~* ^/document$ { return 702;}

配置完毕后,如下图所示:

42_nginx location配置.png

现在,我们重新加载配置文件,具体命令如下:

nginx -s reload

重新加载配置后,我们使用 curl 测试,具体命令如下:

curl -I 127.0.0.1/document

执行完毕后,终端输出如下:

43_nginx location配置.png

即,这里,第一个前缀匹配 ^~ 命中以后不会再搜寻正则匹配,所以会第一个命中。

案例四

我们在 Nginx 的 server 下面增加两个 location 配置,具体配置如下:

location /docu { return 701;}location /doc { return 702;}

配置完毕后,如下图所示:

44_nginx location配置.png

现在,我们重新加载配置文件,具体命令如下:

nginx -s reload

重新加载配置后,我们使用 curl 测试,具体命令如下:

curl -I 127.0.0.1/document

执行完毕后,终端输出如下:

45_nginx location配置.png

这里,即使改变 701 配置和 702 配置的顺序,也一样首先匹配到 701,说明前缀匹配下,返回最长匹配的 location,与 location 所在位置顺序无关。

案例五

我们在 Nginx 的 server 下面增加两个 location 配置,具体配置如下:

location ~ ^/doc[a-z]+ { return 701;}location ~ ^/docu[a-z]+ { return 702;}

配置完毕后,如下图所示:

46_nginx location配置.png

现在,我们重新加载配置文件,具体命令如下:

nginx -s reload

重新加载配置后,我们使用 curl 测试,具体命令如下:

curl -I 127.0.0.1/document

执行完毕后,终端输出如下:

47_nginx location配置.png

现在,我们调换下 701 和 702 的顺序,修改如下:

location ~ ^/docu[a-z]+ { return 702;}location ~ ^/doc[a-z]+ { return 701;}

配置完毕后,如下图所示:

48_nginx location配置.png

现在,我们重新加载配置文件,具体命令如下:

nginx -s reload

重新加载配置后,我们使用 curl 测试,具体命令如下:

curl -I 127.0.0.1/document

执行完毕后,终端输出如下:

49_nginx location配置.png

可见正则匹配是使用文件中的顺序,先匹配成功的返回。

location使用建议

所以实际使用中,个人觉得至少有三个匹配规则定义,如下:

直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。

这里是直接转发给后端应用服务器了,也可以是一个静态首页。第一个必选规则:

location = / { proxy_pass http://tomcat:8080/index}

第二个必选规则是处理静态文件请求,这是 nginx 作为 http 服务器的强项,有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用:

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

第三个规则就是通用规则,用来转发动态请求到后端应用服务器,非静态文件请求就默认是动态请求,自己根据实际把握,毕竟目前的一些框架的流行,带 .php, .jsp 后缀的情况很少了:

location / { proxy_pass http://tomcat:8080/}

Nginx location使用总结

Nginx 中的 location 指令是 nginx 中最关键的指令之一,location 指令的功能是用来匹配不同的 URI 请求,进而对请求做不同的处理和响应,这其中较难理解的是多个 location 的匹配顺序。

开始之前先明确一些约定,我们输入的网址叫做请求 URI,nginx 用请求 URI 与 location 中配置的 URI 做匹配。

嗨客网顶部