nginx location

nginx location官方文档

匹配语法

location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
location [匹配模式] uri {
...
}

location匹配规则

匹配规则总览

匹配模式 匹配符 优先级
精确匹配 = 1
前缀匹配 ^~ 2
正则匹配 ~ 3
正常匹配 uri 4
全匹配(通用匹配) / 5

匹配规则细分

匹配符 匹配规则 优先级
= 精确匹配 1
^~ 以某个字符串开头 2
~ 区分大小写的正则匹配 3
~* 不区分大小写的正则匹配 4
!~ 区分大小写不匹配的正则 5
!~* 不区分大小写不匹配的正则 6
/ 通用匹配,任何请求都会匹配到 7

location匹配优先级

路径匹配优先级

  • 精确匹配 > 前缀匹配 > 正则匹配 > 正常匹配 > 全匹配

匹配示例

精确匹配

⚠️server_name _ 中的_只是一个无效域名的表示方法

编辑nginx配置文件

server {
  listen 80;
  server_name _;
  # 第1段
  location /nginx {
    #return 200 "aaa";
    root /data/nginx/html4/;
    index index.html;
  }

  # 第2段
  location = /nginx {
    #return 200 "bbb";
    root /data/nginx/html3/;
    index index.html;
  }
}

创建网站根目录

mkdir -p /data/nginx/html{3,4}/nginx
echo 'html3' >/data/nginx/html3/nginx/index.html
echo 'html4' >/data/nginx/html4/nginx/index.html

访问测试

$ curl 127.0.0.1/nginx
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

$ curl 127.0.0.1/nginx/
html4

精确匹配中 '/nginx/'中优先匹配到第2段,再访问'/nginx/index.html',此次内部跳转uri已经是/nginx/index.html,而非=的;最终访问结果是第1段中的index.html。

结论:精确匹配区分大小写,不能使用正则,访问的URI必须完全与=后面的一致,多一个"/"或者少一个"/",都是不可以的。

前缀匹配

编辑nginx配置文件

server {
  listen 80;
  server_name _;
  location ^~ /nginx/ {
    rewrite ^ https://www.163.com break;
  }

  location ^~ /nginx/bcd/ {
    rewrite ^ https://www.qq.com break;
  }

  location ^~ /Abc/ {
    rewrite ^ https://www.sina.com.cn break;
  }
}

访问测试

访问127.0.0.1/nginx/,在终端中会返回302,在浏览器中会跳转到www.163.com

$ curl 127.0.0.1/nginx/
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

访问127.0.0.1/nginx/bcd/,在终端中会返回302,在浏览器中会跳转到www.qq.com

⚠️如果bcd后边不加/,跳转页面是www.163.com,即只匹配前缀/nginx

$ curl 127.0.0.1/nginx/bcd/
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

访问一个不存在的页面127.0.0.1/nginx/abcd/,在终端中会返回302,在浏览器中会跳转到www.163.com

$ curl 127.0.0.1/nginx/abcd/
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

访问127.0.0.1/Abc/,在终端中会返回302,在浏览器中会跳转到www.sina.com.cn

$ curl 127.0.0.1/nginx/abc/
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

结论:前缀匹配不能使用正则,区分大小写,只要前缀相同,都可以匹配成功,不管后面有没有字符,保证前缀相同即可。

正则匹配

编辑nginx配置文件

server {
  listen 80;
  server_name _;

  location ~ /[a-z]nginx/ {
    rewrite ^ https://www.baidu.com break;
  }

  location ~* /[a-z]nginx/ {
    rewrite ^ https://www.163.com break;
  }
}

访问测试

访问127.0.0.1/anginx/,在终端中会返回302,在浏览器中会跳转到www.baidu.com

$ curl 127.0.0.1/anginx/
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

访问127.0.0.1/anginx/abc在终端中会返回302,在浏览器中会跳转到www.baidu.com

$ curl 127.0.0.1/anginx/abc/
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

访问127.0.0.1/Anginx/,在终端中会返回302,在浏览器中会跳转到www.163.com

$ curl 127.0.0.1/Anginx/
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

结论:正则匹配 ~ 区分大小写,~* 不区分大小写, 并且与前缀匹配比较类似,只需要匹配模式开头部分,这两种同时存在时,优先匹配区分大小写的。

正常匹配

  • 正常匹配就是匹配模式为空的匹配规则

编辑 nginx配置文件

server {
  listen 80;
  server_name _;

  # 第1段
  location /nginx/ {
    rewrite ^ https://www.baidu.com break;
  }

  # 第2段
  location /[0-9]nginx/ {
    rewrite ^ https://www.qq.com break;
  }
}

访问测试

访问127.0.0.1/nginx/,在终端中会返回302,在浏览器中会跳转到www.baidu.com

$ curl 127.0.0.1/nginx/
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

上述配置文件中第2段访问不生效,404

⚠️location ^~ /nginx/location /nginx/不能同时出现

结论:正常匹配与前缀匹配的差别,只在于优先级。

全匹配(通用匹配)

编辑nginx配置文件

server {
  listen 80;
  server_name _;

  location / {
    root /data/nginx/html;
    index index.html index.htm;
  }
}

全匹配没有匹配模式,并且匹配的uri仅是一个斜杠/,通常用在一个默认页面的地方

命名匹配

命名匹配一般用于静态页面或者错误页面(404,500等),并且这个命名匹配中,不允许有alias。

error_page 404 = @notfound;
location @notfound {
  rewrite ^ https://www.baidu.com break;
}

优先级验证综合实验

编辑nginx配置文件

⚠️前缀匹配和正常匹配不能同时存在

server {
  listen 80;
  server_name _;

  # 全匹配,这里/data/nginx/html/下面有一个nginx文件夹,里面有index.html,内容是nginx location test
  location / {
    root /data/nginx/html;
    index index.html;
  }

  # 正常匹配
  location /nginx/ {
    rewrite ^/nginx/$ https://www.sina.com.cn/ break;
  }

  # 正则匹配
  location ~ /[a-z]ginx/ {
    rewrite ^/nginx/$ https://www.163.com/ break;
  }

  # 前缀匹配
  location ^~ /nginx/ {
    rewrite ^/nginx/$ https://www.baidu.com/ break;
  }

  # 精确匹配
  location = /nginx/ {
    rewrite ^/nginx/$ https://www.qq.com/ break;
  }

}

创建网站根目录

mkdir -p /data/nginx/html/nginx
echo 'nginx location test' > /data/nginx/html/nginx/index.html

第一步、把正常匹配注释掉,留下前缀匹配,然后浏览器访问IP/nginx/,第一次返回的结果是跳转到了www.qq.com,证明了=精确匹配优先级是最大的

第二步、把精确匹配注释掉,然后浏览器访问IP/nginx/,结果是跳转到了www.baidu.com,证明了^~前缀匹配优先级是仅次于精确匹配

第三步、因为前缀匹配和正常匹配不能同时存在,所以这一步比较第一步和第二步,还是把精确匹配注释掉,这次把前缀匹配注释掉,把正常匹配注释打开,结果是跳转到了www.163.com,说明正则匹配的优先级是大于正常匹配的,同时也验证了前缀匹配优先级第2,正则匹配优先级第3,正常匹配优先级第4

第四步、现在只剩下全匹配了,所以全匹配的优先级最低

结论:各匹配优先级如下 精确匹配 > 前缀匹配 > 正则匹配 > 正常匹配 > 全匹配

匹配原则除了这个优先级外,还有一个就是在相同指令模式匹配中,匹配度最大的URI优先

root与alias

nginx配置 location规则中的 uri 往往都是匹配一个目录。

root

编辑nginx配置文件

server {
  listen 80;
  server_name _;

  location /nginx/ {
    root /data/nginx/html/;
    index index.html index.htm;
  }
}

使用root关键字指定网站根目录

当访问127.0.0.1/nginx/index.html时,如果/data/nginx/html/这个目录下没有nginx/index.html或者没有nginx目录,则会报错404

原因是使用root指定目录时,目录下边要包括location后面的uri,否则就会报错

使用root指定目录时,不会将location uri配置的路径去掉,即访问的路径是/data/nginx/html/nginx

访问测试

#不创建目录nginx
mkdir -p /data/nginx/html/
echo 'abc' >/data/nginx.html/index.html

#访问报错404
$ curl 127.0.0.1/nginx/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

alias

编辑nginx配置文件

server {
  listen 80;
  server_name _;

  location /nginx/ {
    alias /data/nginx/html/;
    index index.html index.htm;
  }
}

使用alias关键字指定网站根目录

当访问127.0.0.1/nginx/index.html时,只要保证alias指定的目录中有index.html即可,即使没有目录nginx,它会将location uri配置的路径去掉,实际访问的就是/data/nginx/html/index.html

访问测试

#不创建目录nginx
mkdir -p /data/nginx/html/
echo 'abc' >/data/nginx.html/index.html


$ curl 127.0.0.1/nginx/
abc

结论:root 指定的目录中,需要location中的 uri 路径目录确实存在,alias 指定的目录中不需要 location中的uri 路径目录存在。

代理服务器 proxy_pass 中有无 /

实验环境

角色 主机名 IP
真实web web01 10.0.0.10
nginx代理 nginx-proxy 10.0.0.51

后端真实web服务配置

后端真实web服务nginx 10.0.0.10配置

server {
  listen 80;
  server_name _;

  location /nginx/ {
    root /data/nginx/html/;
    index index.html index.htm;
  }

  location /ng/ {
    root /data/nginx/html/;
    index index.html index.htm;
  }

  location /k8s/ {
    root /data/nginx/html/;
    index index.html index.htm;
  }
}

创建网站根目录

mkdir -p /data/nginx/html/{nginx,ng,k8s}
echo 'nginx' >/data/nginx/html/nginx/index.html
echo 'ng' >/data/nginx/html/ng/index.html
echo 'k8s' >/data/nginx/html/k8s/index.html

访问测试

$ curl 127.0.0.1/nginx/
nginx

$ curl 127.0.0.1/ng/
ng

$ curl 127.0.0.1/k8s/
k8s

proxy_pass无目录无/

代理服务器nginx 10.0.0.51配置中 proxy_pass 无'/'验证

server {
  listen 80;
  server_name _;

  location /nginx {
    #没有/指的是proxy_pass后边的url没有/后缀
    proxy_pass http://10.0.0.10;
  }
}

访问测试

$ curl 10.0.0.51/nginx/
nginx

$ curl -L 10.0.0.51/nginx
nginx

真实web服务10.0.0.10nginx访问日志如下

10.0.0.51 - - [18/Jun/2020:17:46:53 +0800] "GET /nginx/ HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"

结论:如果proxy_pass 反向代理中,在server后面没有 "/" 反斜杠的话,访问的是 http://10.0.0.10/nginx/index.html,它会去上游真实服务器去匹配代理服务器上面location URI。

proxy_pass无目录有/

代理服务器nginx 10.0.0.51配置中 proxy_pass '/'验证

server {
  listen 80;
  server_name _;

  location /nginx {
    #有/指的是proxy_pass后边的url有/后缀
    proxy_pass http://10.0.0.10/;
  }
}

访问测试

因为访问的是真实服务器的/,但是并没有在真实服务器根中写入访问页面

$ curl 10.0.0.51/nginx/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

真实web服务10.0.0.10nginx访问日志如下

10.0.0.51 - - [18/Jun/2020:17:51:32 +0800] "GET / HTTP/1.0" 404 153 "-" "curl/7.29.0" "-"

结论:如果proxy_pass 反向代理中,在server后面有 "/" 反斜杠的话,访问的是 http://10.0.0.10/index.html,它会忽略掉代理服务器上面location中的URI,直接访问代理服务器上面的"/"。

proxy_pass有目录无/

代理服务器10.0.0.51proxy_pass后面增加目录,但不加"/"

server {
  listen 80;
  server_name _;

  location /nginx/ {
    proxy_pass http://10.0.0.10/nginx;
  }
}

访问测试

因为访问的是真实服务器的/,但是并没有在真实服务器根中写入访问页面

$ curl 10.0.0.51/nginx/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

真实web服务10.0.0.10nginx访问日志如下

10.0.0.51 - - [18/Jun/2020:18:04:40 +0800] "GET /nginx HTTP/1.0" 404 153 "-" "curl/7.29.0" "-"

结论:如果proxy_pass 反向代理中,在server后面有URI, 但没有 "/" 反斜杠的话,访问的是 http://10.0.0.10/nginx,它会去上游真实服务器去匹配代理服务器上面的URI。

proxy_pass有目录有/

代理服务器10.0.0.51proxy_pass后面增加目录并且加"/"

server {
  listen 80;
  server_name _;

  location /nginx/ {
    proxy_pass http://10.0.0.10/nginx/;
  }
}

访问测试

$ curl 10.0.0.51/nginx/
nginx

真实web服务10.0.0.10nginx访问日志如下

10.0.0.51 - - [18/Jun/2020:17:58:47 +0800] "GET /nginx/ HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"

结论:如果proxy_pass反向代理中有目录,并且有"/"反斜杠的话,访问的是http://10.0.0.10/nginx/index.html,它会忽略掉代理服务器上面location中的URI,直接访问代理服务器上面的目录+"/"的形式。

测试结果最终对比

情况 proxy_pass配置 访问结果 日志中的访问路径
proxy_pass中无目录无/ location /nginx {
proxy_pass http://10.0.0.10;
}
访问的是 http://10.0.0.10/nginx/index.html,它会去上游真实服务器去匹配代理服务器上面location URI。 /nginx/
proxy_pass中无目录有/ location /nginx {
proxy_pass http://10.0.0.10/;
}
访问的是 http://10.0.0.10/index.html,它会忽略掉代理服务器上面location中的URI,直接访问代理服务器上面的"/"。 /
proxy_pass中有目录无/ location /nginx/ {
proxy_pass http://10.0.0.10/nginx;
}
访问的是 http://10.0.0.10/nginx,它会去上游真实服务器去匹配代理服务器上面的URI。 /nginx
proxy_pass中有目录有/ location /nginx/ {
proxy_pass http://10.0.0.10/nginx/;
}
访问的是 http://10.0.0.10/nginx/index.html,它会忽略掉代理服务器上面location中的URI,直接访问代理服务器上面的目录+"/"的形式。 /nginx/
泡泡吐肥皂o © gitbook.pptfz.top 2021 all right reserved,powered by Gitbook文件修订时间: 秃笔南波湾!!!

results matching ""

    No results matching ""