Shyno
Don't be shy,no problem!

页面请求

当我们在浏览器地址栏输入url时,web会向后端发送请求,请求相关的资源.所以,一般情况下,当我们的url发生变化时.页面会重新向后端发送请求.

 

前端路由

前端路由是有单页面模式的开发情况下衍出来的东西,也就是说:单一页面,无需刷新url,无需向后端请求,从而实现页面部分内容更新.对于前端开发来说,就是不同的路径指向不同的文件.基本的逻辑是,首先有一个主页面,然后将其他的内部内容封装成一个个组件,根据不同的情况将不同的组件展示在主页面的一部分.主页面本身是不变的.对应到前端代码中,它就是index.html.所以基本上的前端框架都会有个index.html,无论它们采取哪种路由方式.

 

路由实现方式

组件的封装都是大同小异的,剩下的就是如何去判断,我怎么去判断如何分配组件,目前是两种方式,一种是hash模式,一种是history模式.

hash模式

 

<a href='#id'>首页</a>

   其实就是window.location.hash.我们先看一下window.location是什么东西.

 

 

是url相关的东西,在这里能看到些眼熟的属性.比如pathname.而hash则是location中#后面的部分,包含"#".我们知道当常规情况浏览的url发生变化时浏览器会向服务器发送请求获取资源,但是hash虽然是url的一部分,它的变化却不会引起发生请求,同时它的变化也能被监听.所以hash模式的几个先决条件是.

   (1)hash是在一个固定的url的后面改变hash值,hash变化并不会导致浏览器发请求

   (2)hash的变化能被监听,会触发window.hashChange事件.

   (3)hash值并不会被放在http请求中

所以我们只需要在window.hashChange写相关逻辑,拿到对应的hash值,然后分配给主页面不同的组件就能实现前端的路由切换.

缺点:hash有个明显的缺点,它是个string,而且是直接拼接到url上的,也就是说如果我要传递参数,将会受到长度限制,而且只能通过字符串拼接.

 

history模式

其实就是window.history,它包含以下内容

 

可以看到它自己并没有任何函数,但是它的原型链上的History有不少方法.包含我们常见的back()、go()等.甚至于它本身只是对History的引用,没有setter函数,所以它是只读的.但是History里面提供了修改方法.

history模式主要利用了pushState()和replaceState(),

history.pushState(stateObj, "page 2", "bar.html")//三个参数分别是  带参 title path

 具体的方案:

<a href='/home'>首页</a>

  (1)处理默认事件.和hash模式不同,当前情况下如果直接点击a标签会发生跳转,刷新页面.所以要阻止a标签默认跳转.

  (2)因为hash改变的hash值,而location改变的pathname,如果不做任何处理,浏览器会发出请求,但是pushState()和replaceState()这两个api会特殊处理,让其修改的时候不会向服务器发送请求.

  (3)因为api提供了额外的参数可以接收跳转传参,而且因为单独存在对象中.所以就没有长度和数据类型限制.然后再通过window.onpopstate的event.state去拿到当前路径下的传进来的参数.

  (4)分配组件,传递参数.

 

缺点:和hash模式一样,它修改了url,但是hash是不会包在http请求里的,可history修改的pathname是会的.虽然你路由跳转并不会向服务器发送请求,但是当页面刷新时,肯定会发请求,而且浏览器的url又是修改过的.这时候就可能出现页面404的问题.

比如原本是http://localhost:8000/index.html,路由跳转之后实际上仍然在index.html上,只不过前端改了其中的某个或全部组件,到了homePage页面,就变成了

http://localhost:8000/index.html----->http://localhost:8000/index.html/homePage

 那么由于history的api的处理,并没有发请求,所以没问题.但是当我刷新页面之后,便会想服务器发送请求http://localhost:8000/index.html/homePage,但是实际上服务器并没有这个页面,而且如果给你配了对应资源,那就不叫前端路由了.所以会出现404.

解决方案:既然前端本身就一个主页面不变,而且无论我url如何改变,实际上都是在index.html上,那服务器就将我所有的浏览器资源请求都改成指向index.html.无论你怎么修改url,都返回给你index.html相关资源.里面的展示内容全交给前端管理.保证不404就行.

 

以上就是两种前端路由跳转方式的大概原理.其中history模式是需要前后端配合的,因为浏览器通过url向服务器发送请求请求静态资源的时候,实际上是通过文件目录去查找的.当前端修改url的时候,目录去找不一定会有相关文件,最明显的是url中homePage是不带后缀的,怎么也得改成homePage.html这种类型的才行,不过除了url不美观外,也不符合路由需求.所以,服务器会配置一个主要的静态资源,比如根目录下放一个index.html,然后将所有的静态资源路径请求都指向index.html(hash模式不需要这步,但也可以).无论是hash还是history模式,其他的组件或者样式解析成json这里数据,请求静态资源时,先给你找到index.html,然后通过解析把相关的数据注入到index.html里面,生成一个完整且每次都可以变化的页面.

 

posted on 2021-09-16 17:51  Shyno  阅读(1143)  评论(0编辑  收藏  举报