history 和 hash 模式

612 阅读5分钟

这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

今天在学习从0到1搭建项目的时候,看到了router中的路由模式,努力回想了下之前学过的知识点,发现自己对这方面知识还是有所匮乏,所以重新再整理学习下

vue3.0

import { createRouter, createWebHistory } from 'vue-router' //createWebHashHistory
import Home from '../views/Home.vue'


const routes = [
    {
        path: '/',
        name: 'Home',
        component: Home
    },
    {
        path: '/about',
        name: 'About',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import('@/views/About.vue')
    }
]


const router = createRouter({
    history: createWebHistory(process.env.BASE_URL), //hash模式:history:createWebHashHistory()
    routes
})


export default router

vue2.X

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
    {
        path: '/login',
        name: '登录',
        component: () => import('@/views/login')
    },
 ]
 
const router = new VueRouter({
    routes
})
export default router

两种路由模式原因 对于 Vue 这类渐进式前端开发框架, 为了构建 SPA(单页面应用), 需要引入前端路由系统, 这也就是 Vue-Router 存在的意义。 前端路由的核心,就在于 —— 改变视图的同时不会向后端发出请求。 因此有两种路由history和hash

hash模式和history模式的区别

hash模式

  1. hash 模式的路由中带有 # 号,比如这个 URL:http://www.abc.com/#/hellohash 的值为 #/hello
  2. hash 模式通过 window.onhashchange 方法监听路由的修改
  3. hash 模式在页面刷新的时候,发送的请求 url 是不带 # 后面的内容的
  4. hash 模式可以兼容部分低版本的浏览器
  5. hash 模式打包后,直接在浏览器中打开 /dist/index.html 可以正常的访问(原因是第 3 条指出的原因)

history模式

  1. history 模式是使用正常的 url 路径显示
  2. history 模式通过 pushState 和 replaceState 方式修改路由改变
  3. history 模式在页面刷新的时候,会请求当前地址栏中完成的 url,这时需要服务器对这个 url 有处理,如果没有对应的文件,需要返回 index.html
  4. history 模式因为是使用的 HTML5 的新规范,所以不能兼容低版本的浏览器
  5. history 模式打包后,直接在浏览器中打开 /dist/index.html 会报错(原因是第 3 条指出的原因)

pushState 和 replaceState方法的区别

History.pushState()

History.pushState()方法用于在历史中添加一条记录。

window.history.pushState(state,title,url)

该方法接受三个参数,依次为:

  • state:一个与添加的记录相关联的状态对象,主要用于popstate事件。该事件触发时,该对象会传入回调函数。也就是说,浏览器会将这个对象序列化以后保留在本地,重新载入这个页面的时候,可以拿到这个对象。如果不需要这个对象,此处可以填null。
  • title:新页面的标题。但是,现在所有浏览器都忽视这个参数,所以这里可以填空字符串。
  • url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。

假定当前网址是example.com/1.html,使用pushState()方法在浏览记录(History 对象)中添加一个新记录。

var stateObj = {foo:'bar'}
history.pushState(stateObj,"page2",'2.html')

添加新纪录后,浏览器地址栏立刻显示 example.com/2.html ,但并不会跳转到2.html,甚至也不会检查2.html是否存在,它只是成为浏览历史中的最新记录。这时,在地址栏输入一个新的地址(比如访问google.com),然后点击了倒退按钮,页面的 URL 将显示2.html;你再点击一次倒退按钮,URL 将显示1.html。

总之,pushState()方法不会触发页面刷新,只是导致 History 对象发生变化,地址栏会有反应。使用该方法之后,就可以用History.state属性读出状态对象。

window.history.state  // {foo:'bar'}

如果pushState的 URL 参数设置了一个新的锚点值(即hash),并不会触发hashchange事件。反过来,如果 URL 的锚点值变了,则会在 History 对象创建一条浏览记录。

如果pushState()方法设置了一个跨域网址,则会报错。

window.history.pushState(null,'','https://twitter.com')

History 对象

一. 概述

window.history属性指向 History 对象,它表示当前窗口的浏览历史。
History 对象保存了当前窗口访问过的所有页面网址。下面代码表示当前窗口一共访问过3个网址。

window.history.length //3

由于安全原因,浏览器不允许脚本读取这些地址,但是允许在地址之间导航。

//后退到前一个网址
history.back()
//等同于
history.go(-1)

浏览器工具栏的“前进”和“后退”按钮,其实就是对 History 对象进行操作。

二. 属性

History 对象主要有两个属性。

  • History.length:当前窗口访问过的网址数量(包括当前网页)
  • History.state:History 堆栈最上层的状态值(详见下文)

三. 方法

History.back()、History.forward()、History.go()

这三个方法用于在历史之中移动。

  • History.back():移动到上一个网址,等同于点击浏览器的后退键。对于第一个访问的网址,该方法无效果。
  • History.forward():移动到下一个网址,等同于点击浏览器的前进键。对于最后一个访问的网址,该方法无效果。
  • History.go():接受一个整数作为参数,以当前网址为基准,移动到参数指定的网址,比如go(1)相当于forward(),go(-1)相当于back()。如果参数超过实际存在的网址范围,该方法无效果;如果不指定参数,默认参数为0,相当于刷新当前页面。

注意,移动到以前访问过的页面时,页面通常是从浏览器缓存之中加载,而不是重新要求服务器发送新的网页。

History.replaceState()

History.replaceState()方法用来修改 History 对象的当前记录,其他都与pushState()方法一模一样。
假定当前网页是example.com/example.html

window.history.pushState({page:1},'','?page=1')
//url显示为http://example.com/example.html?page=1


window.history.pushState({page:2},'','?page=2')
//url显示为http://example.com/example.html?page=2


window.history.replaceState({page:3},'','?page=3')
//url显示为http://example.com/example.html?page=3


window.history.back()
//url显示为http://example.com/example.html?page=1


window.history.back()
//url显示为http://example.com/example.html


window.history.go(2)
//url显示为http://example.com/example.html?page=3

总结:

  • pushState()方法是在历史记录中增加一条新的记录;
  • replaceState()方法是将当前的历史记录给替换掉,传说中的夺舍重生!