浅谈前端路由原理hash和history(代码片段)

星期一研究室 星期一研究室     2022-12-17     542

关键词:

🎹序言

众所周知, hashhistory 在前端面试中是很常考的一道题目。在学习本文内容之前,周一对 hashhistory 的认知可能就在 hashurl 里面多了个 # ,而 history 就不会。然后,我认知里还有一个是只有 history 才能做前后端分离,而 hash 跟前后端分离没有关系。然而,现实是……

对于前端路由来说, hashhistory 都可以用于前后端分离项目,且两者有各自的特点和各自的使用场景,在使用过程中主要要了解当前项目所处的场景,以便于更好地判断使用哪一种路由模式更佳。下面进入本文的讲解~😜

🎸一、前端路由原理

1、SPA

SPA,即单页面应用(Single Page Application)。所谓单页 Web 应用,就是只有一张 Web 页面的应用。单页应用程序 (SPA) 是加载单个 HTML 页面并在用户与应用程序交互时动态更新该页面的 Web 应用程序。浏览器一开始会加载必需的 HTMLCSSJavaScript ,所有的操作都在这张页面上完成,都由 JavaScript 来控制。

现如今,为了配合单页面 Web 应用快速发展的节奏,各类前端组件化技术栈层出不穷。近几年来,通过不断的版本迭代, vuereact 两大技术栈脱颖而出,成为当下最受欢迎的两大技术栈。

2、什么时候需要路由

对于现代开发的项目来说,稍微复杂一点的 SPA ,都需要用到路由。而 vue-router 正是 vue 的路由标配,且 vue-router两种模式hashhistory

下面就依据这两种模式来进行一一讲解。

🎷二、Hash模式

1、定义

hash 模式是一种把前端路由的路径用井号 # 拼接在真实 url 后面的模式。当井号 # 后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 onhashchange 事件。

2、网页url组成部分

(1)了解几个url的属性

属性含义
location.protocal协议
location.hostname主机名
location.host主机
location.port端口号
location.patchname访问页面
location.search搜索内容
location.hash哈希值

(2)演示

下面用一个网址来演示以上属性:

//http://127.0.0.1:8001/01-hash.html?a=100&b=20#/aaa/bbb
location.protocal // 'http:'
localtion.hostname // '127.0.0.1'
location.host // '127.0.0.1:8001'
location.port //8001
location.pathname //'01-hash.html'
location.serach // '?a=100&b=20'
location.hash // '#/aaa/bbb'

3、hash的特点

  • hash变化会触发网页跳转,即浏览器的前进和后退。

  • hash 可以改变 url ,但是不会触发页面重新加载(hash的改变是记录在 window.history 中),即不会刷新页面。也就是说,所有页面的跳转都是在客户端进行操作。因此,这并不算是一次 http 请求,所以这种模式不利于 SEO 优化。hash 只能修改 # 后面的部分,所以只能跳转到与当前 url 同文档的 url

  • hash 通过 window.onhashchange 的方式,来监听 hash 的改变,借此实现无刷新跳转的功能。

  • hash 永远不会提交到 server 端(可以理解为只在前端自生自灭)。

🎺三、History模式

1、定义

history APIH5 提供的新特性,允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求

2、与hash的区别

我们用一个例子来演示, hashhistory 在浏览器下刷新时的区别。具体如下:

正常页面浏览

https://github.com/xxx 刷新页面

https://github.com/xxx/yyy 刷新页面

https://github.com/xxx/yyy/zzz 刷新页面

改造H5 history模式

https://github.com/xxx 刷新页面

https://github.com/xxx/yyy 前端跳转,不刷新页面

https://github.com/xxx/yyy/zzz 前端跳转,不刷新页面

3、history的API

下面阐述几种 HTML5 新增的 history API具体如下表:

API定义
history.pushState(data, title [, url])pushState主要用于往历史记录堆栈顶部添加一条记录。各参数解析如下:①data会在onpopstate事件触发时作为参数传递过去;②title为页面标题,当前所有浏览器都会忽略此参数;③url为页面地址,可选,缺少时表示为当前页地址
history.replaceState(data, title [, url])更改当前的历史记录,参数同上; 上面的pushState是添加,这个更改
history.state用于存储以上方法的data数据,不同浏览器的读写权限不一样
window.onpopstate响应pushState或者replaceState的调用

4、history的特点

对于 history 来说,主要有以下特点:

  • 新的 url 可以是与当前 url 同源的任意 url ,也可以是与当前 url 一样的地址,但是这样会导致的一个问题是,会把重复的这一次操作记录到栈当中。
  • 通过 history.state ,添加任意类型的数据到记录中。
  • 可以额外设置 title 属性,以便后续使用。
  • 通过 pushStatereplaceState 来实现无刷新跳转的功能。

5、存在问题

对于 history 来说,确实解决了不少 hash 存在的问题,但是也带来了新的问题。具体如下:

  • 使用 history 模式时,在对当前的页面进行刷新时,此时浏览器会重新发起请求。如果 nginx 没有匹配得到当前的 url ,就会出现 404 的页面。
  • 而对于 hash 模式来说, 它虽然看着是改变了 url ,但不会被包括在 http 请求中。所以,它算是被用来指导浏览器的动作,并不影响服务器端。因此,改变 hash 并没有真正地改变 url ,所以页面路径还是之前的路径, nginx 也就不会拦截。
  • 因此,在使用 history 模式时,需要通过服务端来允许地址可访问,如果没有设置,就很容易导致出现 404 的局面。

6、两者选择

下面我们再来介绍下在实际的项目中,如何对这两者进行选择。具体如下:

  • to B 的系统推荐用 hash ,相对简单且容易使用,且因为 hashurl 规范不敏感;
  • to C 的系统,可以考虑选择 H5 history ,但是需要服务端支持
  • 能先用简单的,就别用复杂的,要考虑成本和收益

🎻四、结束语

对于 hashhistory 来讲,要清楚两者的区别以及两者各自的使用场景,还有各自的使用特点和优缺点。以上文章只是对前端路由原理的浅谈,希望对大家有帮助~

另下方第三个彩蛋放了一篇关于实现 vue-router 的文章,学有余力的小伙伴有需要自取o!

🐣彩蛋 One More Thing

🏷️参考资料

jarvis👉在SPA项目的路由中,注意hash与history的区别

vue-router官方文档👉vue-router的两种模式

值得一看👉从使用到自己实现简单Vue Router看这个就行了

🏷️番外篇

  • 关注公众号星期一研究室,第一时间关注优质文章,更多精选专栏待你解锁~
  • 如果这篇文章对你有用,记得留个脚印jio再走哦~
  • 以上就是本文的全部内容!我们下期见!👋👋👋

前端路由模式hash和history(代码片段)

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

使用hash和history实现前端历史状态切换,触发事件驱动函数来完成部分数据的加载(使用hash和history实现前端路由切换,含完整源码+注释)(代码片段)

根据loaction下的这个hash值变化,触发事件驱动函数来完成部分数据的加载根据loaction下的这个hash值变化,触发事件驱动函数<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp 查看详情

vue路由的原理及模式(代码片段)

核心:更新视图不重新请求页面。路由的hash模式和history模式。看上去,hash模式就比history模式多了一个#。无论是hash模式还是history模式,在发生改变的时候,浏览器都会新增一个记录,我们就是通过这个记录来实现更新视图但... 查看详情

前端路由原理(代码片段)

...ax获取视图所需json数据。前端路由分两种:hash模式和history模式。hash模式(1)通过a标签、window.location改变hash。hash是URL中#及后面的那部分,改变hash会记入历史栈,不会发起页面请求。(2)通过hashchange事件监听hash变化ÿ... 查看详情

前端路由跳转基本原理(代码片段)

...这些路由插件总是提供两种不同方式的路由方式:Hash和History,有时也会提供 查看详情

关于hash和history的区别和使用(代码片段)

一、区别1、history和hash都是利用浏览器的两种特性实现前端路由,history是利用浏览历史记录栈的API实现,hash是监听location对象hash值变化事件来实现2、history的url没有’#'号,hash反之3、相同的url,history会触发添... 查看详情

hash和history的原理和区别

...监听浏览器的onhashchange()事件变化,查找对应的路由规则history原理:利用H5的history中新增的两个APIpushState()和replaceState()和一个事件onpopstate监听URL变化history模式利用了HTML5HistoryInterface中新增的pushState()和replaceState()方法,这两个... 查看详情

vue-learning:37-router-目录(代码片段)

vue路由vue-router目录前端路由历史服务端渲染(SSR:serversiderender)客户端路由(clientsiderouting)前端路由实现原理hash模式:location.hash和hashChange事件history模式:history和popstate事件vue-routerconstrouter=newVueRouter(option)中的选项对象option路由器 查看详情

vue路由中的hash和history模式(代码片段)

hash和history最明显的区别就是路径上hash比history多一个/#  一、hash模式在我们发请求时例如 http://localhost:8080/#/login 中的#/后面的被称为hash,当hash值发生变化时,浏览器并不会重新发送请求  发请求时并不会把hash带到浏... 查看详情

vue路由中的hash和history模式(代码片段)

hash和history最明显的区别就是路径上hash比history多一个/#  一、hash模式在我们发请求时例如 http://localhost:8080/#/login 中的#/后面的被称为hash,当hash值发生变化时,浏览器并不会重新发送请求  发请求时并不会把hash带到浏... 查看详情

vuerouter路由(代码片段)

...是改变window.location的href属性.location.hash='aaa'HTML5中history模式:1.pushState把urlpush进去,类似栈结构,遵循先入后出history.pushState(,'','home')2.back返回前一页面history.back()3.forward前进下一页面history.forward()4.replaceState替... 查看详情

vue-两种路由模式hash和history

...dash; 改变视图的同时不会向后端发出请求。hash模式和history模式都属于浏览器自身的特性,Vue-Router只是利用了这两个特性(通过调用浏览器提供的接口)来实现前端路由。Hash: History: 查看详情

react路由(代码片段)

...端路由的工作原理:其实是利用前端中的BOM对象中的history这个属性来进行的实现。二、实现前端路由的两种方法:方法一:直接使用H5推出的history身上API。但是有些旧的浏览器可能不支持。这里使用的BrowserRouter方法... 查看详情

react路由(代码片段)

...端路由的工作原理:其实是利用前端中的BOM对象中的history这个属性来进行的实现。二、实现前端路由的两种方法:方法一:直接使用H5推出的history身上API。但是有些旧的浏览器可能不支持。这里使用的BrowserRouter方法... 查看详情

hash和history的区别仅仅是#吗?

...的自由。目前前端路由主要有两种实现方式:hash模式和history模式,下面分别详细说明。hash模式这个我们应该不陌生,比如在用超链接制作锚点跳转的时候,就会发现,url后面跟了"#id",hash值就是url中从"#"号开始到结束的部分has... 查看详情

前端路由原理及vue-router介绍(代码片段)

...须刷新。目前单页面使用的路由就只有两种实现方式hashhistorywww.test.com/##/ 就是HashURL,当 ## 后面的哈希值发生变化时,不会向服务器请求数据,可以通过 hashchange 事件来监听到URL的变化,从而进行跳转页面。&n... 查看详情

vuerouter中模式选择(代码片段)

...路由模式都是使用默认的hash,最近的一个项目中用到了history模式,但是出现一些问题。在这里对着两种模式做一个对比。二、hash模式在VueRouter中默认使用的是hash模式,所以在使用这种模式是不需要设置的,直接默认就行。const... 查看详情

vuerouter实现原理(代码片段)

...de去定义使用具体的路由模式,mode的值如下:hash|history|abstract一、实现方式:hash模式早期的前端路由跳转就是利用location.hash来实现的,像下面的链接 查看详情