前言
我的服务器就只用80端口来完成前端和后端部署(以及多个项目部署),失去了可以区分项目或者前后端入口的端口号,我只能用uri来区分该指向哪个端口或文件,所以使用Nginx是在合适不过了。
但是这路上太多坑,以至于我捣鼓了两天。
下文出现该色号,代表问题所在
目录
1、如何将请求uri切割,将“标志”去除后转发到我的后端项目
1、白屏,能访问到index.html但是无法获取到css/js资源
一、后端代理
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 重写
二、前端代理
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 多个ifnginx 正则匹配配置 - 正义的伙伴! - 博客园
Nginx Location指令配置及常用全局变量_sforiz的博客-CSDN博客
Nginx的location配置剖析 - 枯木逢春 - 博客园
Nginx 重写功能(location / rewrite)_小小考拉123的博客-CSDN博客_nginx 重写