前后端分离后,需要配置 nginx 来实现跨域,代理请求接口到后端服务指定的路径,在进行一段时间的摸索后,记录下对 location 配置,完成前后端的请求转发规则,希望本文对你有所帮助。

location语法

location [modifier] [URI] {
  ...
}

[modifier] 的可选值如下

  • 如果不写修饰符,那么与 [URI] 路径开始匹配。
location /api {
  ...
}

www.a.com/api [匹配]
www.a.com/api/login [匹配]
  • = 精确匹配
location = /api {
  ...
}

www.a.com/api [匹配]
www.a.com/api/login [不匹配]
www.a.com/b/api [不匹配]
  • ~ 区分大小写正则匹配
location ~ /api {
  ...
}

www.a.com/api [匹配]
www.a.com/Api [不匹配]
  • ~* 不区分大小写正则匹配
location ~* /api {
  ...
}

www.a.com/a/b/api [匹配]
www.a.com/ApI [匹配]
www.a.com/b/API [匹配]
  • ^~ 字符串开头匹配,如果匹配到了,就不进行后续到匹配
location ^~ /api {
  ...
}

www.a.com/api [匹配]
www.a.com/api/login [匹配]
www.a.com/bpi [不匹配]

!~ 不匹配(区分大小写)
!~* 不匹配(不区分大小写)
  • @ 内部跳转
location = /index.html {
  error_page 404 @index_error;
}

location @index_error {
  ...
}

nginx实战

前后端分离项目经常会遇到一个场景,前端请求后端时候,需要移除子路径,比如 https://host/api/users 转发到 https://otherhost/users ,那么可以通过 proxy_pass 指令来解决

location ~* ^/api/ {
  proxy_pass https://otherhost/
}

当然也可以配合 rewrite 来解决

location ~* ^/api/ {
  rewrite ^/api/(.*) /$1 break;
  proxy_pass https://otherhost;
}

注意:proxy_pass 最后面的 / 是有区别的,如果最后带 / 代表的是把匹配到的路径去掉,否则会把匹配到的路径拼接上去。例如

location /api/ {
  proxy_pass http://127.0.0.1:8080;
}

如果请求的路径是 /api/user/getName ,上述配置实际转发到真实的地址是:http://127.0.0.1:8080/api/user/getName

location /api/ {
  proxy_pass http://127.0.0.1:8080/;
}

如果请求的路径是 /api/user/getName ,上述配置实际转发到真实的地址是: http://127.0.0.1:8080/user/getName