本地测试/线上部署对Vue应用的路径影响

Vue应用部署到服务器后为“空白页”的解决方法

区别于本地测试环境,路径前面加’/’和不加’/’的区别。

index.html

Vue应用的入口文件

如果之前有建过网站的话应该比较熟悉它了。这文件在本地测试的时候很难想到为什么要有这么个文件,但只要你的网站搭载到apache/nginx且上线后,你就知道为什么要有这么个文件了。

假设你的域名为https://your-website。之前介绍URL的时候提到过,“your-website“是主机名,它对应的是你服务器下的”/var/www/html/“这个路径。

而index.html就相当于一个”入口“。当用户在访问”https://your-website“时,就会查找html这个目录,发现有index.html就会加载该html文档。如果你的index.html放在”/var/www/html/main”文件夹,那么在访问”https://your-website/main”时就会搜索main文件夹,如果有index.html就会加载该html文档。

当然除了index.html之外还有index.php,毕竟本网站用的就是index.php。

准备一台云服务器

区别于localhost

如果你通过Vite创建了一个vue应用,并不作然后其他操作,直接点击index.html,你大概率会得到一个“空白”的页面。此时按下f12,你还会看到几条报错信息–这点我们后面再解释。

空白页

但你如果在“npm run dev”之后再通过”localhost:5173″(假设开放的是5173端口)去访问,你会得到真正的Vue应用的初始界面。

正常运行的Vue初始页面

假设你通过”npm run build”将vue打包并准备部署到服务器上。如果你恰好和我一样有一台服务器,又恰好和我一样在此之前已经部署过了一个网站;又恰好和我一样:为了将新网站和旧网站进行区分管理,在/var/www/html路径下新建了个文件夹(假设文件夹名为web2)放你刚刚新建的Vue应用。你会发现通过”http://你的域名“能正常访问你之前的网站。但是”http://你的域名/web1“加载的仍然是个空白页面。

写者注

这里我强烈建议自己去服务器上试一下,体验过这点之后印象真的会很深刻。(毕竟这个问题太坑人了)

图一的报错原因是“浏览器的同源策略”,而图三的报错原因则是“路径错误”。我们先来介绍一下同源策略。

同源策略

限制JavaScript的跨站点调用

你说得对,但是源…

对于刚创建的默认Vue应用在访问index.html时还会去调用src文件夹下的main.js文件。对于生产版本(dist文件夹下)的vue应用来说,它会调用asset文件夹下的index文件。

简单来说,只有两个文件的URL的协议(http/https),端口(80,22,8080…),主机名都相同时,才能不受同源策略的限制相互通信。

当然,也有不受同源策略限制的,比如重定向或者页面中的链接。也有绕过同源策略的方法,以后碰到再做记录了。

不过上面对应的是通过http协议去访问你的Vue应用。我们再回来看上面的图一

仔细一看,script的路径是本地计算机E盘的路径。而同源策略在CVE-2019-11730后,将所有本地计算机的文件都默认视为“不同源”的。

不过搭建一个本地服务器(npm run dev)就能解决这个问题,这样所有的文件都来自localhost:port,有着相同的源,那自然不会触发CORS错误。

写者注

CORS:Cross-Origin Resource Sharing,即跨源资源共享是一个系统,它由一系列传输的HTTP标头组成,这些 HTTP 标头决定浏览器是否阻止前端 JavaScript 代码获取跨源请求的响应。

路径前面带’/’和不带’/’

根目录访问

这个问题很坑。

假设你的index.html是这样的:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SaveHub</title>
    <script type="module" crossorigin src="/assets/index-0ded4fc5.js"></script>
    <link rel="stylesheet" href="/assets/index-ef4f98ff.css">
  </head>
  <body>
    <div id="app"></div>
    
  </body>
</html>

然后你又恰好和我一样,把这个index.html扔进了”/var/www/html/SaveHub”文件夹,那么你会和我一样得到一个空白页。

接下来我们来看两个链接。一个前面带杠,一个不带。

assets/index.js
/assets/index.js

前者很明显,代表的就是“在assets文件夹下有个index.js文件”。相信这个理解起来还是没啥问题的。而第二条链接前面的’/’代表的则是根目录。在本文章中这个根目录指的就是/var/www/html,表示的是”在html文件夹下有一个assets文件夹,assets文件夹内有个index.js文件“。

两者的区别很明显了,要解决这个问题也有很多种方法。比如我是给链接前加上了一个SaveHub。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/SaveHub/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SaveHub</title>
    <script type="module" crossorigin src="/SaveHub/assets/index-0ded4fc5.js"></script>
    <link rel="stylesheet" href="/SaveHub/assets/index-ef4f98ff.css">
  </head>
  <body>
    <div id="app"></div>
    
  </body>
</html>

写者注

这属于是那种很难被发现,但一看就懂的问题了。也实在是不想做太多解释。不过最感慨的是本地测试的时候由于都是localhost,很难发现这问题。一放到服务器上就开始404。所以还是有个测试用的服务器比较好啊。
Subscribe
提醒
0 评论
Inline Feedbacks
View all comments
0
在此留下你的评论x