面试被问到spa单页应用的router原理是什么?一下就不知道怎么回答,很久前看到锅相关问题,大致是运用了HTML5中history API的pushstate,由于工作中用得少(都是直接上现成的第三方Router库)就没太关注这个。
现在总结一下,前端单页应用的router实现无非是:

pushState

检测浏览器的history对象是否拥有pushState方法,有则直接使用,语法如下:

1
history.pushState(state, title, url);

参数有三个,第2个是历史遗留问题现已忽略,一般传null,其他两个:

  • state:状态对象,作用是可以保存历史数据,因为也是存储在本地磁盘中,可以理解为localStorage等。但是区别是字符大小有限制,超过640kb会报错。通过此参数保存的数据,获取方式为history.state;
  • url变更后的url,这个就是想要跳转到的页面地址,注意点是,必须跟当前url同域;还不仅支持hash跳转,同域下的任意url都行(这也是前端实现SPA路由去“#”号的原理,需服务器端配合)。

location.hash

如果不支持pushState方法, 就直接使用window.location.hash属性更改hash值(路由),同时监听window.onhashchange事件,做跳转后的操作。

1
2
3
window.location = '#foo';
window.location.hash = '#foo';
window.location.hash = 'foo';

以上三种写法在浏览器Chrome都能生效。

注意

请注意pushState()方法绝不会导致hashchange 事件被激活,即使新的URL和旧的只在hash上有区别。

参考

History.pushState() - Web API 接口 | MDN