路由模式-Hash与History浅析

路由

参考

浅谈前端路由原理hash和history
前端路由-hash/history

前端路由的诞生

前端路由的兴起,使得页面渲染由服务器渲染变成了前端渲染。为什么这么说呢!请求一个 URL 地址时,服务器不需要拼接模板,只需返回一个 HTML 即可,一般浏览器拿到的 HTML 是这样的:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>
      Demo
    </title>
    <link href="app.css" rel="stylesheet" />
  </head>
  <body>
    <div id="app"></div>
    <script type="text/javascript" src="app.js"></script>
  </body>
</html>

这里空荡荡的只有一个 <div id="app"></div>,以及一系列的 js 文件,所以说这个 HTML 是不完整的。我们看到的页面是通过这一系列的 js 渲染出来的,也就是前端渲染。前端渲染通过客户端的算力来解决页面的构建,很大程度上缓解了服务端的压力。

单页面开发是趋势,但也不能避重就轻,忽略前端渲染的缺点。由于服务器没有保留完整的 HTML,通过 js 进行动态 DOM 拼接,需要耗费额外的时间,不如服务端渲染速度快,也不利于 SEO 优化。所以说,实际开发中,不能盲目选择渲染方式,一定要基于业务场景。对于没有复杂交互,SEO 要求严格的网站,服务器渲染也是正确的选择。

前端路由路由有hash和history两种

hash模式

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

location属性

//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'

改变hash值的方式

  • a 标签使锚点值变化,例:
  • 通过设置 window.location.hash 的值
  • 浏览器前进键(history.forword())、后退键(history.back())

特点

hash变化会触发网页跳转(模拟跳转,实际由前端渲染)。

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

hash 通过 window.onhashchange 的方式,来监听 hash 的改变。hash 模式路由就是利用 hashchange 事件监听 URL 的变化,从而进行 DOM 操作来模拟页面跳转。

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

History模式

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

History API

window 对象通过 history 对象提供对览器历史记录的访问能力。

  • history.length 出于安全考虑,History 对象不允许未授权代码访问历史记录中其它页面的 URLs,但可以通过 history.length 访问历史记录对象的长度。
  • history.back() 回退到上一个历史记录,同浏览器后退键
  • history.forward() 前进到下一个历史记录,同浏览器前进键
  • history.go(n) 跳转到相应的访问记录;若 n > 0,则前进,若 n < 0,则后退,若 n = 0,则刷新当前页面
  • history.pushState(state, title, URL) pushState 函数会向浏览器的历史记录中添加一条,history.length 的值会 +1,当前浏览器的 URL 变成了新的 URL。需要注意的是:仅仅将浏览器的 URL 变成了新的 URL,页面不会加载、刷新。
  • history.replaceState(state, title, URL)
    • replaceState 的使用与 pushState 非常相似,都是改变当前的 URL,页面不刷新。区别在于 replaceState 是修改了当前的历史记录项而不是新建一个,history.length 的值保持不变。
  • window.onpopstate()
    • 对于通过 history.pushState() 或 history.replaceState() 改变的历史记录,点击浏览器的后退键或前进键页面是没有反应的,那该如何控制页面渲染呢?为了配合 history.pushState() 或 history.replaceState(),HTML5 还新增了一个事件,用于监听 URL 历史记录改变:window.onpopstate()。

特点

- 新的 url 可以是与当前 url 同源的任意 url ,也可以是与当前 url 一样的地址,但是这样会导致的一个问题是,会把重复的这一次操作记录到栈当中。
- 通过 pushState 、 replaceState 来实现无刷新跳转的功能。

Hash与History模式对比

  1. History模式URL地址更直观,Hash模式可读性差
  2. Hash模式兼容性好,History模式不适用于不支持HTML5 history API的低版本浏览器
  3. SEO优化:搜索引擎对History API更友好,对单页应用搜索引擎优化更容易实现。
  4. 使用 History 路由模式实现路由功能需要更多的代码维护。使用 history 模式时,在对当前的页面进行刷新时,此时浏览器会重新发起请求。如果 nginx 没有匹配得到当前的 url ,就会出现 404 的页面。Hash模式没有真正改变url,不需要额外配置。

应用场景

  • to B 的系统推荐用 hash ,相对简单且容易使用,且因为 hash 对 url 规范不敏感;
  • to C 的系统,可以考虑选择 H5 history ,但是需要服务端支持;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jimmy-Enjoy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值