后端路由: 后端服务器根据 url 地址找到对应的html文件,然后把该页面文件发送给浏览器。
前端路由spa: url变化,更新页面组件,但不希望向服务器发送url资源请求
两种方式: hash、history
hash:
window.location.hash # 取值或赋值
window.onhashchange() # 监听变化
改变hash的方式:
- 浏览器地址栏手动更改
- location.hash=
- a标签锚定指定name的a, 或指定id的任意标签
都反映在浏览器url上,都更改location.hash值,且都触发hashchange
hash模式需要注意:
- hash值不会随http请求发送到服务器
- 只修改浏览器的hash部分,按下回车,浏览器不会发送任何请求给服务器,只会触发hashchange事件并且修改location.hash的值
- hash模式下,手动刷新页面不会向浏览器发送请求,不会触发hashchange事件,但是会触发window.onload事件
- hash写入时,会在不重载网页的前提下,创造一条访问历史记录,使用"后退"按钮,就可以回到上一个位置。上述规则对IE 6和IE 7不成立,它们不会因为#的改变而增加历史记录。
history:
history.pushState(stateObj,title,url)
history.replaceState(stateObj,title,url)
history.back()、forward()、go()
window.onpopstate()
history.state # 堆栈最上层的状态值,当前历史记录的状态对象
history模式需要注意:
- pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录,两个 API 都会操作浏览器的历史记录,而不会引起页面的刷新。
- 浏览器的前进与后退(按钮、back、forward、go ),会触发window.onpopstate事件。
- 超出栈的go back不会触发 onpopstate
- state对象最大640k,否则异常
- popstate事件的回调函数中获取当前的历史记录的状态对象的拷贝。但是,这两个对象并不相同,简单的说e.state是history.state的深拷贝。
两种模式的差异 & 需要注意:
hash
模式只可以更改 # 后面的内容,因此只能设置与当前 URL 同文档的 URL;
History
模式可以通过pushState() API 设置任意的同源 URL;hash
设置的新值必须与原来不一样才会触发动作将记录添加到栈中;Hash模式下, 多次刷新为同一个页面的话,记录只添加一次;history.pushState()
设置的新 URL 可以与当前 URL 一模一样,这样也会把记录添加到栈中;hash
模式只能更改哈希值,也就是字符串;History
模式可以通过pushState() stateObject 参数可以添加任意类型的数据到记录中;- pushState() 可额外设置 title 属性供后续使用,目前没有用。
当然啦,history 也不是样样都好。SPA 虽然在浏览器里游刃有余,但真要通过 URL 向后端发起 HTTP 请求时,两者的差异就来了。尤其在用户手动输入 URL 后回车,或者刷新(重启)浏览器的时候。
hash
模式下,仅 hash 符号之前的内容会被包含在请求中, 模式无需后端配置,并且兼容性好。history
模式,前端的 URL 必须和实际向后端发起请求的 URL 一致,如果后端缺少对 /book/id 的路由处理,将返回 404 错误。后端需要配置 index.html 页面用于匹配不到静态资源的时候,或者开启NGINX配置
hashchange、popstate触发条件:
同时触发
loaction.hash = ‘’
都不触发
,即使当pushState函数设置url参数的值为hash格式时,也不会触发hashchange事件
history.pushstate({},'','history’)
history.replacestate({},'','history’)
触发popstate,有hash改变会触发hashchange
按钮、history.go、back、forward
注意事项:超出栈的go back不会触发 popstate
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。