如何配置nginx多路径?

1. 问题&背景

有以下三种路径:

  1. /prefix
  2. /prefix/dist
  3. /prefix/非dist非空

需求:

  1. http://www.abc.com/prefix或者 http://www.abc.com/prefix/可以访问index.html
  2. http://www.abc.com/prefix/dist/static/js/vendor.js可以访问静态资源
  3. http://www.abc.com/prefix/coupon/v1(可以理解为prefix后,非dist非空的情况)转发到后端的服务

文件的加载顺序:

  1. 请求http://www.abc.com/prefix加载index.html
  2. 请求http://www.abc.com/prefix/dist/static/js/vendor.js
  3. 请求http://www.abc.com/prefix/coupon/v1

2. 我的实现

server {
    listen       80;
    server_name  www.abc.com;
    charset utf-8;
    
    location /prefix {
        alias /usr/local/somepath;
        add_header X-debug-message "=========配置A==========" always;
        index index.html;
    }

    location /prefix/dist {
        alias /usr/local/somepath;
        add_header X-debug-message "==========配置B========" always;
        try_files $uri $uri/ =404;
    }

    location ~* ^\/prefix/(?!(dist)).+$ {
        add_header X-debug-message "==========配置C========" always;
        proxy_pass http://127.0.0.1:6666;
    }
}

3. 遇到问题

发起第一个请求获取html的时候,报404,因为走了配置C;

clipboard.png

4. 自己的分析&尝试

  1. 已经尝试过去掉配置C,这种情况能顺利加载http://www.abc.com/prefixhttp://www.abc.com/prefix/dist/static/js/vendor.js
  2. 根据location的匹配规则,验证完prefix string之后,再去验证正则,如果正则没有通过,则采用匹配的prefix string规则;
  3. 自己验证过正则,是写对了,见这里
  4. 也用过这篇文章介绍的pcretest方法验证,正则的写法也是没错误的
  5. 但是跑起来的时候还是会匹配http://www.abc.com/prefix或者 http://www.abc.com/prefix/导致404

5. 请教

  1. 如果用正则匹配“非dist非空”,我的方法有什么问题?
  2. 或者有没有其他思路解决这个需求?
阅读 5.7k
1 个回答

因为你的第三个 location 表达式刚好匹配 http://www.abc.com/prefix/index.html.

所以, 只需要将第一个 location 跳转后的地址排除在第三个 location 即可, 如

- location ~* ^\/prefix/(?!(dist)).+$ {
+ location ~* ^\/prefix/(?!(dist|index\.html)).+$ {

参考

nginx location 测试工具
https://nginx.viraptor.info/

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题