上一期咱们讲了如何在一个新服务器上用 Nginx 跑起一个前端我的项目,然而还有很多缺点,比方咱们想在这个 Nginx 下跑多个我的项目怎么办,spa 单页我的项目常见的刷新空白起因及解决等等,本篇将一一介绍。
同端口多我的项目配置
假如咱们有两个单页我的项目,一个 pc 官网,一个 mobile 官网,咱们都想跑在上期 8082 端口上,这时候发现咱们上一期部署的文件夹是间接放在 www
目录下的,这可不行,文件全放这上面都不能辨别是哪个我的项目的了,万一文件夹或者文件名字一样,就笼罩掉了。
那么有两种计划:
- 各大 cli 脚手架上都有输入文件夹的设置,比方 vue-cli 的
outputDir
,这个能够设置文件夹名。 - 在 www 目录下新建对应我的项目的文件夹,scp 上传上传到对应文件夹。
这里咱们应用一下计划 1,计划二相似,门路不同而已。
批改打包配置
因为咱们是在同一个端口下跑的我的项目,那么咱们只能通过门路辨别不同我的项目。
比方咱们的我的项目在 http://localhost:8082/mobile
下跑,那么 vue-router 增加 base 配置:
new VueRouter({
mode: 'history',
base: '/mobile', // pc 同理
...
)}
当然我更倡议你把这个门路值放入.env 文件里,.env.dev
:
BASE_URL=/mobile
批改配置为:
new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
...
)}
// history: createWebHistory(process.env.BASE_URL) // 4.0+
vue.config.js:
module.exports = {
publicPath: process.env.BASE_URL, // 这个是打包后内部文件链接追加值,比方 '/mobile',那么最初的 js 和 css 链接为 '/mobile/js/xxxx.js'
outputDir: 'mobile', // 这个是打包输入文件夹名
...
}
进行我的项目打包,会失去一个 mobile 文件夹,咱们应用 scp 进行文件上传(pc 同理)
scp -r ./mobile root@$host:~/nginx/www/; # 上传 mobile 文件
Nginx 配置批改
location /pc {
alias /usr/share/nginx/html/pc/;
index index.html;
}
location /mobile {
alias /usr/share/nginx/html/mobile/;
index index.html;
}
重启 nginx,docker restart web
,此时拜访 http://localhost:8082/mobile/
,网页能失常关上,过后咱们拜访http://localhost:8082/mobile
却发现被诡异的重定向到了 80 端口,也就是http://localhost/mobile/
,查看一下浏览器申请发现被 301 永恒重定向了。
这是因为 Nginx 在拜访 URI 时;如果拜访资源为一个目录,且结尾没有 /
,那么 Nginx 会进行一个 301 重定向到结尾带有 ’/’ 的地址,跳转时能够通过port_in_redirec
设置跳转端口号,没有的话则从 listen
里取,也就是 80,故这里进行了 80 的重定向,咱们能够在 server
模块中增加 absolute_redirect off;
敞开这个重定向。
设置之后重启 Nginx,咱们通过 http://localhost/mobile
和http://localhost/pc
都能拜访对应我的项目。
spa 单页跳转刷新白屏
咱们在下面进行了多我的项目配置,然而还有一个问题没有解决,这个问题很常见,就是跳转后刷新的白屏问题,很多同学不敢从 hash 路由切换到 history 路由也是有此起因。
简略形容一下问题吧:咱们间接关上我的项目的根门路地址拜访失常,比方下面的 http://localhost/mobile
,刷新也失常显示,咱们点击跳转到http://localhost/mobile/list
,此时也失常跳转,然而咱们在这个地址进行原地刷新时,会呈现 404 谬误,或者说咱们间接用浏览器关上http://localhost/mobile/list
也会呈现 404,这个问题呢算比较严重的了,也就是咱们能间接关上或者刷新的只有根门路,其余门路都会呈现 404 的问题。
404 的起因
首先咱们的网页拜访都是一个 get 申请,你能够了解为获取一个动态资源,咱们看一下 Nginx 的 location 配置:
location /pc {
alias /usr/share/nginx/html/pc/;
index index.html;
}
当咱们的 URI 地址匹配到了 /pc,会在 alias 的门路中查找,默认文件去找 index 指令前面的的 index.html,比方咱们拜访 http://localhost/mobile
能失常拜访,是因为 mobile 目录下的确有 index.html 这个实体文件,那么失常返回了,而拜访http://localhost/mobile/list
,Nginx 就会去找mobile/list/index.html
,很显然没有这个货色,故返回 404。
总结一下就是:spa 的路由是由 js 生成的,并不会有对应门路的实体文件,而 Nginx 拜访网页的实体资源,找不到就会返回 404,那么也就是这个门路是交由咱们的 js 来解决,而不是交由 Nginx 解决,所以咱们只须要在 Nginx 找不到门路的实体文件时把咱们的 index.html 返回回去就行了。
location /pc {
alias /usr/share/nginx/html/pc/;
try_files $uri $uri/ /pc/index.html;
index index.html;
}
try_files
指令会顺次查找前面的文件,直到找不到,$uri
是原地址,$uri/
是$uri/index.html
,剩下的就是/pc/index.html
,举个例子http://localhost/pc/aaa.png
,会先去查找http://localhost/pc/aaa.png
,找不到的话查问http://localhost/pc/aaa.png/index.html
,最初则是http://localhost/pc/index.html
ok,这样 spa 白屏问题就解决了,然而还有一个渺小的问题,那就是当咱们拜访的门路的确不存在(spa-router 也没有),门路不是 Nginx 解决了,那么此时 404 也就不存在了,会呈现白屏,不过聪慧的同学曾经想到了泛滥 router 都会在最初加个通配符来匹配 404 的页面,那么 404 的页面也就交给咱们本人写了。
root 和 alias
这个算是一个补充吧,说一下 root
和alias
的区别,毕竟很多配置用的 root
,请留神alias
只能在 location
中应用,而 root
能够配置在 http
,server
,location
中应用。
其实 root
和alias
都是 Nginx 指定文件门路的指令,以下面的例子:
# root
location /pc {
root /usr/share/nginx/html;
try_files $uri $uri/ /pc/index.html;
index index.html;
}
# alias
location /pc {
alias /usr/share/nginx/html/pc/;
try_files $uri $uri/ /pc/index.html;
index index.html;
}
这两个的匹配规定一样的,简略来说就是 root 会把 location 前面配置的门路加上,alias 则是去除掉,也就是说二者的文件门路都是指向根目录下的 pc
文件夹,也就是说应用 root
的 location 匹配的门路必须实在存在(因为追加了),如果 root
呈现 404 了间接看 path 的目录是否存在就行了。
不过须要留神一点就是 alias 的门路结尾须要有个/
,尽管这里加不加都没问题,但这是一个良好的习惯,请放弃,否则遇到上面这种状况就会出错。以上面例子别离拜访http://localhost:8082/image/logo.png
,最初一个会 404:
location /image/ {alias /usr/share/nginx/html/image/;}
location /image {alias /usr/share/nginx/html/image/;}
location /image {alias /usr/share/nginx/html/image;}
location /image/ { # 这里会 404
alias /usr/share/nginx/html/image;
}
下一篇我会介绍单页利用在 Nginx 上的加载优化,尽请期待。
本系列更新只有利用周末和下班时间整顿,比拟多的内容的话更新会比较慢,心愿能对你有所帮忙,请多多 star 或点赞珍藏反对一下
本文地址:https://xuxin123.com/web/nginx-spa