记录Nginx部署Angular项目的坑

发布于:2023-01-10 ⋅ 阅读:(523) ⋅ 点赞:(0)

前言

我的服务器就只用80端口来完成前端和后端部署(以及多个项目部署),失去了可以区分项目或者前后端入口的端口号,我只能用uri来区分该指向哪个端口或文件,所以使用Nginx是在合适不过了。

但是这路上太多坑,以至于我捣鼓了两天。

下文出现该色号,代表问题所在


目录

前言

一、后端代理

1、如何将请求uri切割,将“标志”去除后转发到我的后端项目

二、前端代理

1、白屏,能访问到index.html但是无法获取到css/js资源

2、正常点击很正常,一刷新就404

3、我觉得的正确的部署前端


一、后端代理

1、如何将请求uri切割,将“标志”去除后转发到我的后端项目

这里的“标志”,指的是让nginx匹配到某一个标志后,将该请求转发到后端项目。

但是有一个问题,虽然Nginx可以匹配到该标志并执行转发,但是转发的时候会把该标志一起转发到我的后端项目

例如:
向nginx请求"http://88.88.88.88:80/api/user/login",
此时的标志为"api",而我的后端项目正确的requestMapping为“/user/login”,
如果设置为 ↓ ,实际上后端项目接收到的请求是“/api/user/login”,这完全不对。

       location ^~ /api/ {
                proxy_pass     http://127.0.0.1:8083;
                #8083为后端服务的端口号
        }

解决办法:

       location ^~ /api/ {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header REMOTE-HOST $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                if ($request_uri ~ ^/api/(.*)$) {
                        proxy_pass     http://127.0.0.1:8083/$1;
                }
        }

解释一下上面的意思:用if里面的正则表达式,获得"/api/"后面的字符串,再通过proxy_pass转发到我的后端项目去,并且接上正则匹配到的值($1就是获取到的值),这样就完美代理到后端了~

参考链接:

Nginx 重写功能(location / rewrite)_小小考拉123的博客-CSDN博客_nginx 重写

Nginx的location配置剖析 - 枯木逢春 - 博客园

nginx 正则匹配配置 - 正义的伙伴! - 博客园

nginx中许多if判断的写法_bst@微胖子的博客-CSDN博客_nginx 多个if


二、前端代理

1、白屏,能访问到index.html但是无法获取到css/js资源

开开心心将前端"ng build",文件夹传到服务器,解压,配置location一气呵成,结果一访问给我白屏(白屏算幸运,404才是不幸)。

这时候不要慌,打开控制台一看,是一堆js和css文件获取404,这时候打开nginx的errorLog看,访问的资源路径是错的(angular项目获取资源路径的锅),难怪获取不到。

环境描述:

angular项目打包后放在ubuntu的 “/home/mysystem/super”(文件夹权限777,该文件夹直接是项目文件夹)
nginx配置如下

        location ^~ /super/ {
                root    /home/mysystem/super;
                index   index.html index.htm;
        }

这样我访问“http://88.88.88.88:80/super/”是可以访问到我文件夹的index.html,但是显示为白屏,一看控制台显示资源获取404,查看Nginx的errorLog,显示获取资源的链接为“http://88.88.88.88:80/main.5ddb79566e563878.js”、“http://88.88.88.88:80/runtime.047ac70204747e7e.js”、...

这压根就不会往super文夹找资源,难怪获取不到

解决办法1 - 不推荐

        #增加对/的匹配,让js/css往正确的文件夹加载

        location ~* \.(js|css)$ {
               root    /home/mysystem/super/;
        }

但是这么做,有点捡了芝麻丢了西瓜了,不推荐,虽然奏效。

解决办法2 - 推荐
先知道为什么会往 / 获取资源,观察一下白屏的浏览器地址,是不是“标志”被修改为你的angular项目的默认地址了,例如我的默认地址为“/main”,我访问“http:88.88.88.88:80/super/”会变成“http:88.88.88.88:80/main”,这是angular路由自己的地址,看到这个也不奇怪为什么会往 / 获取资源了。

修改angular项目src目录index.html的<base href="/">标签,在href加上你的标志,这样angular应用就会以/super/为起始点进行路由、获取资源,正好请求到Nginx设定的规则。

<base href="/">
改为
<base href="/super/">

2、正常点击很正常,一刷新就404

解决的白屏后,又遇到了刷新404,苦上加苦。

这个问题我觉得有两个:
        一个是angular路由的起始点不对,也就是第一个问题说的<base href="">,uri无法被Nginx匹配到;
        第二个是即使Nginx的location匹配到你,也只会傻傻的往文件夹找资源,而我们的地址是angular的路由地址,是没有实际文件的,所以404。

环境描述:

angular项目打包后放在ubuntu的 “/home/mysystem/super”(文件夹权限777,该文件夹直接是项目文件夹)

解决办法:
步骤1:修改angular项目的<base href="/">的标签

<base href="/">
改为
<base href="/super/">
super为location匹配的标志

步骤2:往location加try_files

        location ^~ /super/ {
                root    /home/mysystem/;
                #用标志来进入文件夹,这里不直接写到super文件夹
                index   index.html index.htm;
                try_files $uri $uri/ /super/index.html;
                #加了这句会向浏览器传回index.html并且附上你的uri,让angular自己路由
        }

3、我觉得的正确的部署前端

A、正确的项目放置位置

Nginx提供了一个默认的html文件夹,在Nginx根目录名为“html”,如果nginx没有配置正确文件目录,会默认往这个文件夹去找东西,并且“html”被Nginx当做为“/”目录。

所以我觉得应该将项目放在该目录下,所以我在该目录下设置了一个软链接,指向真实的项目地址。

ln -s /home/mysystem/super super

这样我们还可以在location里面省一个root的配置

        location ^~ /super/ {
                index   index.html index.htm;
        }

B、angular项目的base标签设置正确

base标签引导angular的路由和资源的获取前置地址,如果不设置成Nginx里面我们设定的“标志”,那angular的静态资源和路由都会自动打偏,访问不到我们设定的“super”。

angular的base标签在src目录下的“index.html”,在里面添加Nginx设定的“标志”,这样angular访问东西才会默认带上这个标志

<base href="/">
改为
<base href="/super/">
super为location匹配的标志

C、刷新时让angular自己路由而不是获取服务器资源

即使正确的设定访问前缀,每次都往“super”访问,但是angular路由的地址直接拿来往Nginx访问的话,也会出现访问不到资源404的情况,因为该地址是路由地址而不是资源地址,没有实质文件,所以我们在location里面添加try_files配置,实现让angular自己路由自己的地址。

        location ^~ /super/ {
                index   index.html index.htm;
                try_files $uri $uri/ /super/index.html;
                #这里我们的项目是放在html文件夹里面的,所以需要进入项目文件夹super才有index.html
                #加了这句会向浏览器传回index.html并且附上你的uri,让angular自己路由
        }

参考链接:

Nginx 重写功能(location / rewrite)_小小考拉123的博客-CSDN博客_nginx 重写

Nginx服务器的rewrite、全局变量、重定向和防盗链相关功能 - 走看看

nginx $1,2,3的含义_zhuwei_clark的博客-CSDN博客_nginx中$1

nginx之if判断、变量设置、$1_cxy1991xm的博客-CSDN博客_nginx 判断相等

VUE项目部署Nginx后访问正常,刷新就会404_从入职到删库的博客-CSDN博客_nginx vue 刷新404
nginx中许多if判断的写法_bst@微胖子的博客-CSDN博客_nginx 多个if

nginx 正则匹配配置 - 正义的伙伴! - 博客园
Nginx Location指令配置及常用全局变量_sforiz的博客-CSDN博客

 

Nginx的location配置剖析 - 枯木逢春 - 博客园

Nginx 重写功能(location / rewrite)_小小考拉123的博客-CSDN博客_nginx 重写

Nginx的try_files指令详解_zzhongcy的博客-CSDN博客_nginx try_files

nginx配置选项try_files详解_势无形的博客-CSDN博客_tryfiles