hash

这里的 hash 就是指 url 尾巴后的 # 号以及后面的字符。这里的 # 和 css 里的 # 是一个意思。hash 也 称作 锚点,本身是用来做页面定位的,她可以使对应 id 的元素显示在可视区域内。
由于 hash 值变化不会导致浏览器向服务器发出请求,而且 hash 改变会触发 hashchange 事件,浏览器的进后退也能对其进行控制。
hash 路由:监听 url 中 hash 的变化,然后渲染不同的内容,这种路由不向服务器发送请求,不需要服务端的支持;
当页面中的 hash 发生变化时,会触发hashchange事件

  1. //监听hash路由
  2. window.addEventListener('hashchange', function(){
  3. // 监听hash变化,点击浏览器的前进后退会触发
  4. })

history模式

首先,hash 本来是拿来做页面定位的,如果拿来做路由的话,原来的锚点功能就不能用了。其次,hash 的传参是基于 url 的,如果要传递复杂的数据,会有体积的限制,而 history 模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中。
history 模式改变 url 的方式会导致浏览器向服务器发送请求,这不是我们想看到的,我们需要在服务器端做处理:如果匹配不到任何静态资源,则应该始终返回同一个 html 页面。
history 路由:监听 url 中的路径变化,需要客户端和服务端共同的支持;

  • back():后退到上一个路由;
  • forward():前进到下一个路由,如果有的话;
  • go(number):进入到任意一个路由,正数为前进,负数为后退;
  • pushState(obj, title, url):前进到指定的 URL,不刷新页面;
  • replaceState(obj, title, url):用 url 替换当前的路由,不刷新页面; ```javascript const rawPushState = window.history.pushState; window.history.pushState(state, title, url) { rawPushState.apply(window.history, state); //改变路由历史记录 } // state:需要保存的数据,这个数据在触发popstate事件时,可以在event.state里获取 // title:标题,基本没用,一般传 null // url:设定新的历史记录的 url。新的 url 与当前 url 的 origin 必须是一樣的,否则会抛出错误。url可以是绝对路径,也可以是相对路径。 //如 当前url是 https://www.baidu.com/a/,执行history.pushState(null, null, ‘./qq/‘),则变成 https://www.baidu.com/a/qq/, //执行history.pushState(null, null, ‘/qq/‘),则变成 https://www.baidu.com/qq/

const rawReplaceState = window.history.replaceState; window.history.replaceState(state, title, url){ rawReplaceState.apply(window.history, state) } // 与 pushState 基本相同,但她是修改当前历史记录,而 pushState 是创建新的历史记录

window.addEventListener(“popstate”, function() { // 监听浏览器前进后退事件,pushState 与 replaceState 方法不会触发
}); ```

总结

hash模式和history模式的区别:
1、hash模式较丑,history模式较优雅;
2、pushState设置的新URL可以是与当前URL同源的任意URL;而hash只可修改#后面的部分,故只可设置与当前同文档的URL;
3、pushState设置的新URL可以与当前URL一模一样,这样也会把记录添加到栈中;而hash设置的新值必须与原来不一样才会触发记录添加到栈中;
4、pushState通过stateObject可以添加任意类型的数据到记录中;而hash只可添加短字符串;
5、pushState可额外设置title属性供后续使用;
6、hash兼容IE8以上,history兼容IE10以上;
7、history模式需要后端配合将所有访问都指向index.html,否则用户刷新页面,会导致404错误。