Nginx location 配置总结记录
in Note with 0 comment
Nginx location 配置总结记录
in Note with 0 comment

语法规则

location optional_modifier location_match {
  . . .
}

optional_modifier有以下几个值:

匹配顺序

下面验证一下匹配顺序,通过输出 X-location来判断哪个location起作用

情形一:只有精确匹配(=)

...
location = /baidu {
  rewrite ^/baidu(.*) /$1 break;
  add_header X-location '= /baidu';
  proxy_pass https://www.baidu.com;
}
...
curl -I http://localhost/baidu

HTTP/1.1 200 OK
Server: nginx/1.17.4
...
X-location: = /baidu

情形二:^~正则匹配共同起作用时,用^~处理请求。尽管正则匹配location_match更长

...
location ~ ^/baidu {
  rewrite ^/baidu /$1 break;
  add_header X-location '~ ^/baidu';
  proxy_pass https://www.baidu.com;
}

location ^~ /bai {
  rewrite ^/baidu /$1 break;
  add_header X-location '^~ /bai';
  proxy_pass https://www.baidu.com;
}
...
curl -I -X GET http://localhost/baidu

HTTP/1.1 200 OK
Server: nginx/1.17.4
...
X-location: ^~ /bai

情形三:(none)正则匹配共同起作用时,用最先出现正则匹配处理请求。尽管(none)location_match更长

...
location /baidu {
  rewrite ^/baidu /$1 break;
  add_header X-location '/baidu';
  proxy_pass https://www.baidu.com;
}

location ~ ^/bai {
  rewrite ^/baidu /$1 break;
  add_header X-location '~ ^/bai';
  proxy_pass https://www.baidu.com;
}

location ~* ^/baid {
  rewrite ^/baidu /$1 break;
  add_header X-location '~* ^/baid';
  proxy_pass https://www.baidu.com;
}
...
curl -I http://localhost/baidu

HTTP/1.1 200 OK
Server: nginx/1.17.4
...
X-location: ~ ^/bai

更换一下正则匹配的先后顺序

...
location /baidu {
  rewrite ^/baidu /$1 break;
  add_header X-location '/baidu';
  proxy_pass https://www.baidu.com;
}

location ~* ^/baid {
  rewrite ^/baidu /$1 break;
  add_header X-location '~* ^/baid';
  proxy_pass https://www.baidu.com;
}

location ~ ^/bai {
  rewrite ^/baidu /$1 break;
  add_header X-location '~ ^/bai';
  proxy_pass https://www.baidu.com;

...
curl -I http://localhost/baidu

HTTP/1.1 200 OK
Server: nginx/1.17.4
...
X-location: ~* ^/baid

URIproxy_pass的影响

具体Demo,以下例子中URI/

情形一:proxy_pass无URI,location_match尾斜杠

location /api/ {
    proxy_pass http://www.baidu.com;
}

#http://localhost/api/               =>         http://www.baidu.com/api/
#http://localhost/api/xx             =>         http://www.baidu.com/api/xx
#http://localhost/api-xx             =>         不匹配

情形二:proxy_pass无URI,location_match尾斜杠

location /api {
    proxy_pass http://www.baidu.com;
}

#http://localhost/api/               =>         http://www.baidu.com/api/
#http://localhost/api/xx             =>         http://www.baidu.com/api/xx
#http://localhost/api-xx             =>         http://www.baidu.com/api-xx

情形三:proxy_pass有URI,location_match尾斜杠

location /api/ {
    proxy_pass http://www.baidu.com/;
}

#http://localhost/api/               =>         http://www.baidu.com/
#http://localhost/api/xx             =>         http://www.baidu.com/xx
#http://localhost/api-xx             =>         不匹配

情形四:proxy_pass有URI,location_match尾斜杠。容易踩坑,应避免使用。

location /api {
    proxy_pass http://www.baidu.com/;
}

#http://localhost/api                =>         http://www.baidu.com/
#http://localhost/api/               =>         http://www.baidu.com//
#http://localhost/api/xx             =>         http://www.baidu.com//xx
#http://localhost/api-xx             =>         http://www.baidu.com/-xx

内部重定向指令

index: 只处理以尾斜杠结束的请求。按指定顺序索引文件

/请求会被内部重定向到/index.html

location = / {
  index index.html;
}

location / {
  ...
}

try_files: 按指定顺序进行索引,可以索引文件和目录,存在尾斜杠就会索引目录

设置默认图片

location /images/ {
  try_files $uri /images/default.gif;
}

location = /images/default.gif {
  expires 30s;
}

按顺序索引多个文件,实在找不到就返回404

location / {
  try_files $uri $uri/index.html $uri.html =404;
}

前端 SPA 部署

location / {
  root /usr/share/nginx/html;
  try_files $uri $uri/ /index.html;
}

rewrite: 使用正则表达式替换请求URI,可通过设置lastbreakredirectpermanent来决定进一步的处理方式

/v2-web或者/v2-web/替换为空, 并继续匹配其他location

location ~ ^/v2-web/? {
  rewrite ^(/v2-web/?)(.*) /$2 last;
}

/v2-web或者/v2-web/替换为空, 停止匹配其他location

location ~ ^/v2-web/? {
  rewrite ^(/v2-web/?)(.*) /$2 break;
  proxy_pass http://www.baidu.com;
}

302重定向到百度

location ~ ^/baidu {
  rewrite ^/(.*)$ http://www.baidu.com redirect;
}

301重定向到百度

location ~ ^/baidu {
  rewrite ^/(.*)$ http://www.baidu.com permanent;
}

error_page: 不同的错误码响应不同的处理结果

404错误由http://backend进行响应

location / {
  error_page 404 = @fallback;
}

location @fallback {
  proxy_pass http://backend;
}

参考资料

proxy_pass url 反向代理的坑
proxy_pass反向代理配置中url后面加不加/的说明
nginx的proxy_pass和 location为正则表达式的问题
Understanding Nginx Server and Location Block Selection Algorithms
How to stop nginx 301 auto redirect when trailing slash is not in URI?

The article has been posted for too long and comments have been automatically closed.