一.history 详解
history 对象包含用户(在浏览器窗口中)访问过得 URL。 history 对象是 window 对象的一部分,可以通过 window.history 属性对其进行访问。
- 属性
- history.length 返回浏览器历史列表中的 URL 数量
- 方法
- back() 加载 history 列表中的前一个 URL
- forward() 加载 history 列表中的下一个 URL
- go() 接受一个整数作为参数,加载 history 列表中的某个具体页面,如果参数超过实际存在的网址范围,该方法无效,如果不指定参数,默认参数为 0,相当于刷新当前页面。
- pushState(state, title, url)向 history 中添加一条记录。添加新的记录后,浏览器并不会跳转到新的地址,甚至不会检查这个地址是否存在,他只是成为浏览器历史中的最新记录。总之 pushState()方法不会触发页面刷新,只是导致 history 对象发生变化,地址栏展示会有变化。pushState()方法设置一个跨域网址会报错,目的是:防止恶意代码让用户以为是在另一个网址上,因为 pushState 并不会导致页面跳转。
state 一个与添加的记录相关联的状态对象,主要用于pushState事件,该事件触发时,该对象会传入回调函数。浏览器会将这个对象序列化以后保留在本地,重新载入这个页面的时候,可以拿到这个对象,如果不需要这个对象,可以填null
title 新页面的标题,现在浏览器基本都会忽略这个参数,可以填空字符串
url 新的网址,必须与当前页面处在同一个域,浏览器地址栏会显示这个网址
let state={index:1,desc:'描述'}
history.pushState(state,'标题','/detail/page1')
console.log(window.history.state) // {index:1,desc:'描述'}
- replaceState() 方法用来修改 history 对象的当前记录,其他都与 pushState()方法一模一样。总结:pushState() 在历史记录中增加一条新的记录,replaceState()将当前的历史记录给替换掉。
- 注意
- 由于安全原因,浏览器不允许脚本读取这些地址,但是允许这些地址之间导航,浏览器工具栏的“前进”和“后退”按钮,其实就是对 history 对象进行操作
- 移动到以前访问过的页面时,页面通常从浏览器中加载,而不是重新要求服务器发送新的网页
二.hash 详解
location 对象包含有当前 URL 的信息 location 对象是 window 对象的一部分,可以通过 window.location 属性来访问 hash 设置或返回从井号(#)开始的 URL(锚) 设置 location 对象的 hash 属性,那么浏览器会转移到当前文档中的指定位置
- 特点
- hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从#号开始的部分)
- http 请求不包含#部分
- location.hash 改变不会触发网页重载
- 改变 hash 会改变浏览器的访问历史
三.对比
- history.pushState() 设置新的 url 可以是与当前 url 同源的任意 url,而 hash 只可修改#后面的部分,因此只能设置与当前 url 同文档的 url
- pushState()设置新的 url 可以与当前 url 一模一样,这样也会把记录添加到栈中,而 hash 设置的新值必须与原来不一样才会触发动作将记录添加到栈中。
- pushState(state,title,url) state 参数可以添加任意类型的数据到记录中,而 hash 只可添加短字符串
- hash 模式下,仅 hash 符号之前的内容被包含在请求中,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。history 模式下,前端的 url 必须和实际向后端发起请求的 url 一致,如 www.abc.com/book/id 如果后端缺少对 /book/id 的路由的处理,将会返回 404 错误。所以在使用 history 模式时,如果 url 匹配不到任何静态资源,则应该返回同一个 index 页面。