了解啥是hash路由和history路由

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解啥是hash路由和history路由相关的知识,希望对你有一定的参考价值。

参考技术A hash 路由:监听 url 中 hash 的变化,然后渲染不同的内容,这种路由不向服务器发送请求,不需要服务端的支持;
history 路由:监听 url 中的路径变化,需要客户端和服务端共同的支持;
我们一步步实现这两种路由,来深入理解下底层的实现原理。我们主要实现以下几个简单的功能:

1.监听路由的变化,当路由发生变化时,可以作出动作;
2.可以前进或者后退;
3.可以配置路由;

当页面中的 hash 发生变化时,会触发hashchange事件,因此我们可以监听这个事件,来判断路由是否发生了变化。

事件hashchange只会在 hash 发生变化时才能触发,而第一次进入到页面时并不会触发这个事件,因此我们还需要监听load事件。

在 history 路由中,我们一定会使用window.history中的方法,常见的操作有:

back():后退到上一个路由;
forward():前进到下一个路由,如果有的话;
go(number):进入到任意一个路由,正数为前进,负数为后退;
pushState(obj, title, url):前进到指定的 URL,不刷新页面;
replaceState(obj, title, url):用 url 替换当前的路由,不刷新页面;
调用这几种方式时,都会只是修改了当前页面的 URL,页面的内容没有任何的变化。但前 3 个方法只是路由历史记录的前进或者后退,无法跳转到指定的 URL;而pushState和replaceState可以跳转到指定的 URL。如果有面试官问起这个问题“如何仅修改页面的 URL,而不发送请求”,那么答案就是这 5 种方法。

如果服务端没有新更新的 url 时,一刷新浏览器就会报错,因为刷新浏览器后,是真实地向服务器发送了一个 http 的网页请求。因此若要使用 history 路由,需要服务端的支持。

当我们用 history 的路由时,必然要能监听到路由的变化才行。全局有个 popstate 事件,别看这个事件名称中有个 state 关键词,但 pushState 和 replaceState 被调用时,是不会触发触发 popstate 事件的,只有上面列举的前 3 个方法会触发

针对这种情况,我们可以使用 window.dispatchEvent 添加事件:

然后就可以添加对这两个方法的监听了:

前端路由模式hash和history

  1. hash模式
    hash模式的原理是依据window对象的onhashchange事件进行监听,它的特点是:虽然hash路径出现在URL中,但是不会出现在HTTP请求中,对后端完全没有影响,因此改变hash值不会重新加载页面。
    window.onhashchange = function(e){
          console.log(e);
    }

    打印出来的结果
    技术分享图片
    可以通过location.hash获得浏览器url路径中的#部分内容,上图是#bvc,
    如果想获取#后面的内容可通过location.hash.slice(1),上图是bvc

  2. history模式
    利用了HTML5 History Interface中新增的pushState()replaceState()方法,这两个方法应用于浏览器的历史记录栈,在当前已有的back、forward、go的基础上,他们提供了对当前浏览器进行修改的功能,只是当它们被修改时,虽然浏览器的URL发生
    了变化,但是不会立即向后端服务器发送请求,但是如果点击刷新,就会重新向后端服务器发送请求。
  3. 使用场景
    一般情况下,vue-router前端路由模式使用history和hash都可以,在美观上history比hash美观些,因为hash有自己的特定符号#
    相比于hash,history具有以下优势:
    *pushState()设置新的URL可以是任意与当前URL同源的URL,而hash只能改变#后面的内容,因此只能设置与当前URL同文档的URL
    *pushState()设置的URL与当前URL一模一样时也会被添加到历史记录栈中,而hash模式中,#后面的内容必须被修改才会被添加到新的记录栈中
    *pushState()可以通过stateObject参数添加任意类型的数据到记录中,而hash只能添加短字符串
    *pushState()可额外设置title属性供后续使用
    但是通过URL向后端发起HTTP请求的时候,history,hash具有以下区别
    *hash模式下,只有#符号之前的内容才会包含在请求中被发送到后端,也就是说虽然后端没有对路由全覆盖,但是不会返回404错误
    *history模式下,前端的URL必须和向发送请求后端URL保持一致,否则会报404错误
















以上是关于了解啥是hash路由和history路由的主要内容,如果未能解决你的问题,请参考以下文章

浅谈前端路由原理hash和history

hash路由和history路由的区别

Vue-两种路由模式 hash 和 history

路由 前后端渲染 url hash 和 html5 history

hash和history的原理和区别

Vue路由中的hash和history模式