1. 介绍

location指令是http模块当中最核心的一项配置,根据预先定义的URL匹配规则来接收用户发送的请求,根据匹配结果,将请求转发到后台服务器、非法的请求直接拒绝并返回403、404、500错误处理等。

2. location指令语法

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

语法规则很简单,一个location关键字,后面跟着可选的修饰符,然后是URI要匹配的字符,花括号中是要执行的操作。

3. URI匹配模式

location指令分为两种匹配模式:

  1. 普通字符串匹配:以=^~开头,或者无正则修饰符~~*(例如 /abc/def)开头的规则
  2. 正则匹配:以~~*开头表示正则匹配,~*表示正则不区分大小写

4. URI匹配过程

总体的匹配原则是:先匹配普通字符串模式,再匹配正则模式。

  1. 先查找是否有=开头的精确匹配。如果有,则直接匹配,不进行后续查找。
  2. 继续普通匹配,并按照最长前缀原则进行。

2.1 如果最长的匹配前缀location带有^~修饰符,Nginx将立即停止搜索并选择该location。

2.2 如果最长的匹配前缀location未使用^~修饰符,则该匹配项将被临时存储,并且将继续下面的匹配。

  1. 查找区分大小写~和不区分大小写~*的正则表达式location。

3.1 如果有正则表达式location也能匹配,则选用第一个与之匹配的正则表达式location。

3.2 如果没有正则表达式location匹配,则选用2.2中暂存的location。

总结以下3点:

  • (location =) > (location ^~ 非正则路径) > (location ~,~* 正则路径) > (location 非正则路径) > (location /)
  • 普通匹配中,同等优先级的,按照最长前缀匹配
  • 正则匹配中,使用第一个匹配到的正则

示例1

location  = / {
  # 精确匹配 / ,主机名后面不能带任何字符串
  [ configuration A ] 
}

location  / {
  # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
  # 但是正则和普通字符会优先匹配
  [ configuration B ] 
}

示例2

location ^~ /images/ {
  # 有这条在,下面的 B和 C始终不会匹配
  [ configuration A ] 
}

location /images/或者/images/abc/等 {
  # 如果去掉 A,那么 B会被暂存,直到发现下面的 C,就匹配 C,如果没有 C,则用 B
  [ configuration B ] 
}

location ~ /images/或者/images/abc/等 {
  [ configuration C ] 
}

示例3

location /documents/ {
  [ configuration A ]
}

location ~ /documents/ {
  [ configuration B ]
}

location ~ /documents/abc {
  [ configuration C ] 
}

URI为/documents/或者/documents/abc时,都匹配 B,因为正则按照顺序,匹配第一个。

5. URL尾部的/需不需要

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

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

参考:

Nginx Location Directive Explained

彻底弄懂 Nginx location 匹配

http://nginx.org/en/docs/http/ngx_http_core_module.html#location

最后修改日期: 2021年5月28日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。