记录一次与nginx大战近4天的问题
前言
关于nginx把我拿捏
准备把招新系统合并到学校服务器上已有的项目上里,于是先在测试端口进行测试,发现老旧项目占用了nginx的主路由,于是我只能想办法让招新系统在nginx上开二级路由并配合前端BrowserRouter路由。接下来就是厮杀时刻…
出现的问题:首次进入 https://XXXX.cn/enroll的时候没有问题(因为我已经在nginx配置了一个关于enroll的路由,该路由具体细节往下看)但是一旦前端路由跳转的时候或者刷新浏览器网页的时候,页面直接404完犊子
老项目占用的配置如下:

就是说我现在不能改变默认location的配置,还有nginx上/static/的匹配配置
一、为什么点击前端路由跳转返回404?
nginx的路由如下:
build文件即为react打包后的文件

打开开发者网络选项卡,发现html的请求的路径为https://xxxx.cn/enroll/home 首先先分析哪个location会拦截到这个请求,这个毫无疑问,肯定是location为/enroll会拦截到,然后再去build目录下找home文件夹,结果发现找不到,因此报错404,关于css与js都是请求不到的,因为/static/被老项目占用了,请求路径不对导致找不到对应资源了。
二、为什么一刷新页面就无了
这个问题其实和上面那个问题是一样的,因为一刷新,请求的路径会变成类似https://xxxx.cn/enroll/xxx,而这种请求会被nginx的/enroll拦截,同理,后面的发生的事情就和上面一样了。
三、解决方案
错误示例1:既然请求路径不对,那么我可以在location为/enroll的代码块中用rewrite重新对路径进行改写,然后让请求路径对于/enroll后面的所有参数都忽略掉,这样请求就都变成了https://xxxx.cn/enroll 这样显然是不对的,因为这会导致一种循环匹配,也不知道为啥当时想到了这种方式,可能是太专注于解决路径问题了,脑子抽了。
错误示例2:既然改写路径然后重新匹配会有循环的问题,那么我又想到可以把/enroll后面的参数收集起来然后拼接成正确的路径,做法如下:

其中$enroll为上面我set的一个常量即build的那个文件目录(/home/kelab/oj_recruiment/build)
结果发现一个问题,html文件200了,css和js直接g了,这也不难想到为啥g了,对,还是那个路径问题,css和js请求的路径类似https://xxxx.cn/static/xxx.css 看到这里会发现enroll怎么不见了?这是因为前端页面配置里面默认是以根路径,所有才会从域名后直接拼接/static来发起请求,到了这里这个问题的正解已经不远了,终于拨开云雾见月明了。
正确示例:

说明: 第一个location的目的在于将所有静态css,js资源请求的路径设置正确,第二个location的目的在于将所有以/enroll开头的请求路径重写(相当于去除掉/enroll后面的所有参数),不过这种写法需要前端配合,在package.json中加上homepage:"/enroll/",目的在于页面请求的静态资源都会带上/enroll,
例如请求css的路径会变成:https://xxxx.cn/enroll/static/xxx.css,
这个写法还可以优化,因为完全可以直接用第一个location的手法将enroll后面的路径匹配上,然后再正确的改写路径。
tips:对于nginx里面例如location的匹配规则和try_files,alias不太了解的小伙伴可以去先看看相关的基础解释,包括react-router的homepage有什么作用,例如:
nginx中文文档
https://blog.csdn.net/RedaTao/article/details/109095165,
https://blog.csdn.net/a20023930/article/details/80436663
总结
关于我这种情况是需要前端和nginx都相互配合一下才能完成,前端的react需要在package.json中设置homepage来改变请求静态资源的路径,nginx上需要配置/enroll的location来对请求进行改写请求路径。我相信还有更好的解决办法。
本文记录了作者在将新项目整合到已有nginx配置时遇到的挑战,如何通过配置二级路由、rewrite规则和前端路由设置来解决动态路径404及刷新问题。重点讲述了nginx的location配置和前端package.json的配合使用。
1012

被折叠的 条评论
为什么被折叠?



