SPA单页面项目厉害的地方之一就是切换路由时不会发送http请求到服务端,而是在客户端渲染,这就需要引入前端路由,也就是浏览器的hash或history属性。
hash :
hash ,url中带有# 路由即#后面的部分。虽然出现在 URL 中,但不会被包含在 http 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面,也不会发送http请求。
当hash改变时,会触发hashchange事件,监听该事件,对页面进行更新。如果请求了一个不存在的页面则会返回一个空白页面
history :
history 利用了 html5 history interface 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器记录栈,在当前已有的 back、forward、go 基础之上,它们提供了对历史记录 修改的功能(pushState将传入url直接压入历史记录栈,replaceState将传入url替换当前历史记录栈)。
当它们执行修改时,虽然改变了当前的 URL ,但浏览器不会立即向后端发送请求。而是先匹配自己配置的组件路由,如果存在则不会发送HTTP请求,如果不存在则会请求HTTP返回404页面,也可以自己提前配置好如果访问路由不存在就进入其他自定义页面。
history 对比 hash
优势:
pushState 设置的 url 可以是同源下的任意 url ;而 hash 只能修改 # 后面的部分,因此只能设置当前 url 同文档的 url。
pushState 设置的新的 url 可以与当前 url 一样,这样也会把记录添加到栈中;hash 设置的新值不能与原来的一样,一样的值不会触发动作将记录添加到栈中。
pushState 通过 stateObject 参数可以将任何数据类型添加到记录中;hash 只能添加短字符串。
pushState 可以设置额外的 title 属性供后续使用。
劣势:
history 在刷新页面时,如果服务器中没有相应的响应或资源,就会出现404。因此,如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
hash 模式下,仅 # 之前的内容包含在 http 请求中,对后端来说,即使没有对路由做到全面覆盖,也不会报 404。