线上问题描述:

香港某站点登陆后跳转 dashboard 页面,刷新页面后报错 403 Forbidden。

问题定位:

前端目录文件下有命名为 dashboard 的文件夹,与路由重名 以下为 nginx 部分配置文件代码:

location /entry {
    index entry.html
}
location / {
    ...
     autoindex on;
     index index.html;
     try_files $uri $uri/ /index.html
}

打开 autoindex,从下图可以得出命中了第二条$uri/规则,但该目录下没有 index.html,nginx 尝试检索目录但是被禁止,所以报错 403。

为什么刷新后才报错?

第一次请求是 xxx.com/,命中 index.html,VueRouter 在 history 模式下,login 成功后,借助 history.pushState 实现页面的无刷新跳转到了 /,这种方式改变了 url,之后再根据判断权限点通过 redirect 跳转到对应的页面。如果重新刷新页面会造成一个新的 http 请求,因此会重新请求服务器,如果 nginx 没有匹配到当前 url,就会出现报错页面。

xxx.com/dashboard,按照 try_files 匹配顺序走到了$uri/,而目录中正好命中了 dashboard 文件夹,然而其中没有 index.html,nginx 尝试检索目录但是被禁止,于是报错 403 Forbidden。

为什么测试环境没有报错?

测试环境的 nginx 配置文件代码为:

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

永远不会命中 dashboard 文件夹,所以不会有这个问题,但也无法命中其他文件夹下的 index.html 因此 $uri/ 不能移除。

如何规避该问题?

在 public 目录下禁止放置与路由重名的文件,资源文件可放置在 src 目录下。