以上几个教程里所使用的测试vue项目
(demo1)
均是十分简单的项目,完全没涉及到router路由
或者其他的知识,今天一位小哥将自己的项目部署到nginx
后,发现某些页面在访问的时候偶尔会出现404
找不到,因此找到我,共同解决了这个问题。在解决过程中,发现这其实也是个老生常谈
的问题,最主要就是vue项目的路由采用了history模式
,才导致了这个问题。
既然问题已经找到了,那么就应该探究下为什么会出现这个问题:
-
1.首先我们先理解一下SPA(单页Web应用)的概念:
由于我们是使用vue搭建的
单页web应用(SPA)
,就是只有一个Web页面的应用,是在打开页面的时候加载单个HTML页面(index.html),在用户与程序交互的时候动态获取数据(axios)的Web页面程序。
单页面应用程序:
只有在第一次才会向后台请求页面,之后的每次请求都是去获取到必要的数据,由页面上的js解析数据后动态展示到页面上传统单页面程序:
每次页面的跳转都是去服务器请求页面因此,单页面应用程序的优势就体现出来了:
减少请求的密度,加快了页面的响应速度,降低了服务器上的压力,有着更好的用户体验,让用户在web app上也能感受到native app的流畅。
-
2.引出路由
既然是单页面程序,那么我们看到的页面跳转是什么情况呢?一个页面怎么会来回跳转呢?此时就理所应当的引出vue中的重中之重,vue-router(单页面应用程序的路径管理器
)。
vue的单页面应用是基于路由
+组件
的,路由用于设定访问路径
,并且将路径
与组件
进行连接;在传统的多页面应用中,是使用一些超链接来进行页面跳转与切换的;而在vue-router中,不是页面的切换,而是组件的切换,所以,路由的本质就是
建立起url和组件之间的映射关系
-
vue-router的工作原理是什么呢?
SPA(single page application):单页面应用程序,其中只有一个完整的页面(index.html);它在加载页面的时候,不会加载所有页面,而是只更新某个指定的容器中的内容。单页面应用程序的核心之一就是:更新视图而不重新请求页面;vue-router在实现单页面前端路由的时候,提供了两种方式:Hash模式与History模式,根据**mode参数来自由选择采用什么方式。 -
- Hash模式
vue-router默然采用的就是Hash模式---采用URL的Hash来模拟一个完整的URL,于是当URL发生改变的时候,页面不会重新加载。hash(#)是URL的锚点,代表的是网页中的一个位置,单单改变#后面的部分,浏览器只会滚动到相应的位置,而不会去后端请求网页资源,也就是说#是用来指导浏览器动作的,对服务器端完全不起作用,HTTP请求中也不包括#;同时每一次改变#后面的部分,都会在浏览器的访问历史中增加一个记录,当使用浏览器的“后退”按钮的时候,就可以返回上一个位置;所以说Hash模式是使用锚点值的改变,根据不同的值,渲染指定DOM元素的不同数据。
- Hash模式
-
- history模式
由于Hash模式中会在URL上自带#,如果不想要很丑的#的话,我们可以使用路由的history模式,只需要在配置路由规则的时候,加入值:mode:'hostory'
,这种模式充分利用了history.pushState API来完成URL跳转而无需重新加载页面。
- history模式
//main.js文件中
const router = new VueRouter({
mode: 'history',
routes: [...]
})
当你在使用history模式的时候,URL就会像是正常的URL,没有#存在,比较美观。不过这种模式如果不加以配置的话,会有一个深坑,深坑出现的原因简单介绍一下:
当我们使用history模式的时候进行页面跳转的时候,其vue-router原理是使用HTML5的新接口pushState和replaceState
,这两个接口的最大的特点就是改变URL地址,但却不刷新页面,注意!!!仅仅改变网址,网页不是真正的跳转了,也不会获取到新的资源,本质上,网页还是停留在原来的页面(index.html)。
举个栗子:
打开首页后,你的URL显示www.xxx.com/home,这时候能正常显示,没问题,此时你进入到注册页,URL此时是www.xxx.com/home/reg,这个时候,当你点击刷新时,浏览器就会拿着当前的地址www.xxx.com/home/reg去后台请求该资源,后台肯定没有对应的资源,所以就会报404找不到,这样就很明了了!该怎样解决呢?
栗子中出现的问题,我们可以想想一下,假如一旦浏览器向服务器请求找不到404时,就还跳回到最初的index.html页面,页面再根据URL上的路径跳转到对应的组件里不就好了嘛!事实上,我们就是这么取解决的,在服务器上进行以下相关配置即可解决该问题!
vue-router history后端配置例子
至此,还问题的前因后果已经讲清楚了,以后再遇到类似的问题也会有解决思路了,这样就很好,希望以后一直坚持住!
页面知识参考自:
https://blog.csdn.net/weixin_45111741/article/details/101028344
https://blog.csdn.net/sinat_17775997/article/details/80688397