当然这是针对一次bug解决引发对底层原理的探究
整个文章将以如下的部分进行展开:
- 理解报错需要的一些前置知识
- 错误场景
- bug错误描述
- 为什么会产生这个报错
- 怎么解决这个报错
理解报错需要的一些前置知识
前端路由方面:
对于vue的项目前端一般会有两个属性来设置路由,一个是路由基准路径base,还有一个是配置文件的publicPath,两个属性,这边简单说下用法,
**base:**如果你设置了base的路径比如设置为app/那么这个时候你访问这个服务的时候是要正常带上这个app的前缀,也就是类似这样127.0.0.1:8080/app来访问服务,但是资源的物理路径跟这个是没有关系的(也就是你此时的资源根目录还是放在承载这服务的nginx里配置的根目录)
**publicPath:**如果你这里设置了publicPath,比如设置为xiaosi/ ,那么你这个时候访问资源的时候,在这个前端项目中所有的资源请求都会带上这个前缀xiaosi,但是base是不会的,同时这里的如果没有特殊配置的话,这里的访问的资源需要在嵌套一层物理目录(也就是你的资源需要放在承载服务的nginx配置的资源根目录下的xiaosi目录下)。
总结区别就是一个需要承载物理路径,同时每个请求会自动加上相应前缀,另一个则是配了一个虚拟根路径,资源承载路径不需要嵌套(个人理解,仅供参考!)
具体可以参考这个博客,说的比较清楚
vue-router的base和vue.config.js的publicPath区别和联系_vue-router base-CSDN博客
区分前端环境的方式一般都是通过环境变量来做区别,变量注入的方式大致分为四种:
- 通过启动服务时注入
- 通过环境变量文件注入.env
- 通过packe.json设置启动命令注入
- 在vue.config.json中显式设置
ng相关知识:
allias / 转发路径
在 Nginx 中,alias 指令用于定义一个位置块中请求的真实路径,它是一个强大的功能,允许开发者重定向请求到服务器上的不同目录。这与 root 指令不同,root 指令会将位置块中的 URI 与指定的路径合并来形成文件的真实路径。而 alias 则是将位置块中的路径替换为指定的路径。
针对请求转发:在nginx配置中有一块是配置try_files的,这个的大致意思是当请求进入相对应的location块的时候对请求路径进行逐个尝试,如果文件存在则匹配结束,请求通过,如果都匹配不上,一般最后会配置一个兜底的内部重定向,不至于返回报错页面,这个是大概的逻辑,但是重点都不在这里,重点是这里的try_files的设置的选项是url,这里的url逻辑是不会改变请求给出的url的,也就是说,是原原本本照抄路径上的部分去尝试。这里放个nginx配置示例,以免你们不知道我在说什么。

举个例子,按照以上的配置逻辑,此时我请求127.0.0.1:8080/web/index.html
这个时候提取出来的url为 /web/index.html 没错!你没看错,这个时候的web是会被带上给到前端项目里的(嘿嘿!如果是这样配置的话,然后你资源还放在html目录下,那么指定是会白屏的,别慌,本文就是解决这个问题的。)
这边也将一些优秀的i资源放在这里
一文搞懂 Nginx 中的 try_files 与 uri:解决 SPA 路由刷新 404 核心配置_nginx location try files uri-CSDN博客
kuboard相关:
配置字典:(本人理解)对于容器内的一些环境变量进行配置或者做一些目录挂载,配置文件与容器关联。
具体参看官方文档:https://kuboard.cn/learning/k8s-intermediate/config/config-map.html
好了前置知识唠完了,现在进入问题出现与解决部分
错误场景
前端服务以nginx容器的形式由k8s承载,经过k8s的ip加url部分来区分不同的服务(由k8s的ingress做流量区分)。
例如:k8sip为192.168.78.66
前端1:192.168.78.66:8080/qianduan1 前端项目base / publicPath /qianduan1
前端2:192.168.78.66:8080/qianduan2 前端项目base / publicPath /qianduan2
但是两个服务的里默认的nginx配置都是如下:

bug错误描述
然后导致请求192.168.78.66:8080/qianduan1 这个服务的时候出现白屏,在请求表现上为无论请求啥文件(静态或者主页或者ico文件响应都是index.html)
为什么会产生这个报错
有了前置知识,那这个白屏问题就很简单了,依题意得,通过ingress转发(本质其实是一个ng)以后,请求确实能够到达前端对应的容器,但是这个时候由于nginx的转发特性,如果没有做请求重写的操作的话,这个qianduan1前缀是会被带入到容器内的nginx的,然后由于容器内的根目录在/opt下面,又由于全部资源并没有嵌套一层qianduan1的文件夹,所以什么资源都找不到,直接触发最后一个请求,重定向到index.html,好,真相大白,一切都清楚了,那么问题就好解决了!(芜湖!我tm在这边耗了一上午,但是我整理这个blog好像时间也不短,不过本着记录的习惯还是写了,说不定会回来看呢!鬼知道呢!)
怎么解决这个报错
- 在第一个nginx(ingress)重写location里的资源请求,但是显然不现实4
- 可以在容器内的nginx通过rewrite 来重写请求,解决嵌套的qianduan1前缀,具体参看百度
- 可以在容器内的nginx通过allias重定向属性来做资源重定向,解决嵌套的qianduan1前缀,就像这样

- 或者你在物理资源上妥协,也就是加一层物理目录,也就是qianduan1(不过这太蠢了,相信没人会用吧,也不灵活,换个环境还得改,不然还得寄)
提供解决方案如上四个(好吧,其实也就两个有价值,如果有大佬有别的思路欢迎给出,我及时完善)。
一些题外话(别的思路):
其实我当时在想能不能不改ng,通过改前端的两个路由属性来解决,但是好像不太现实,其实吧,也能改,就是前端控制base的路径为qianduan1/然后publicPath不变,理论上可以,但是我当时看前端写死了,改动太大,就算了,不了了之。