转载:https://segmentfault.com/a/1190000014822765
前端路由是直接找到与地址匹配的一个组件或对象并将其渲染出来。改变浏览器地址而不向服务器发出请求
有两种方式:
1. 在地址中加入#以欺骗浏览器,地址的改变是由于正在进行页内导航
2. 使用H5的window.history功能,使用URL的Hash来模拟一个完整的URL。
两种模式比较
一般的需求场景中,hash
模式与history
模式是差不多的,根据MDN
的介绍,调用history.pushState()
相比于直接修改hash
主要有以下优势:
pushState
设置的新url
可以是与当前url
同源的任意url
,而hash
只可修改#
后面的部分,故只可设置与当前同文档的url
pushState
设置的新url
可以与当前url
一模一样,这样也会把记录添加到栈中,而hash
设置的新值必须与原来不一样才会触发记录添加到栈中pushState
通过stateObject
可以添加任意类型的数据记录中,而hash
只可添加短字符串pushState
可额外设置title
属性供后续使用
history
模式的问题
对于单页应用来说,理想的使用场景是仅在进入应用时加载index.html
,后续在的网络操作通过ajax
完成,不会根据url
重新请求页面,但是如果用户直接在地址栏中输入并回车,浏览器重启重新加载等特殊情况。
hash
模式仅改变hash
部分的内容,而hash
部分是不会包含在http
请求中的(hash
带#
):
http://oursite.com/#/user/id //如请求,只会发送http://oursite.com/
所以hash
模式下遇到根据url
请求页面不会有问题
而history
模式则将url
修改的就和正常请求后端的url
一样(history
不带#
)
http://oursite.com/user/id
如果这种向后端发送请求的话,后端没有配置对应/user/id
的get
路由处理,会返回404
错误。
官方推荐的解决办法是在服务端增加一个覆盖所有情况的候选资源:如果 URL
匹配不到任何静态资源,则应该返回同一个 index.html
页面,这个页面就是你 app
依赖的页面。同时这么做以后,服务器就不再返回 404
错误页面,因为对于所有路径都会返回 index.html
文件。为了避免这种情况,在 Vue
应用里面覆盖所有的路由情况,然后在给出一个 404
页面。或者,如果是用 Node.js
作后台,可以使用服务端的路由来匹配 URL
,当没有匹配到路由的时候返回 404
,从而实现 fallback
。