计算机网络中,路由器是指工作在网络层,转发IP数据包的一种设备。
web服务器端编程中,用户浏览器请求一个URL,服务器根据这个URL返回对应的页面。这种请求URL和返回内容的对应关系,通常配置在一个文件里,管理这些配置的应用程序组件叫“路由器”。
后来人们提出了前后端分离、SPA应用这些概念,为了保持和原来一致的用户体验,我们可以使用JavaScript在浏览器前端模拟一个“路由器”,根据不同的URL,在界面上加载不同的组件树(更底层的理解就是DOM树)。
SPA前端路由通常是如下这种形式。
http://www.gacfox.com/index.html#/path1
井号本来是用作页面上的锚点,URL中出现井号有一个特点,井号后面的内容改变不会触发页面重新加载,但是会触发hashchange
事件,前端路由就是据此实现的(和jsonp之类的技术一样,属于有点hack的写法,代码难看且难以理解,但没办法,这属于历史遗留问题)。
下面例子中编写了一个前端“路由器”,虽然并没有实际操作组件树,只是换了一下<div>
的颜色,不过思路是一致的,这里就不文字解释了,解释起来也比较曲折,直接上代码。
<body>
<div id="app" style="width: 100px; height: 100px; background: red;"></div>
<a href="#/path1">red</a>
<a href="#/path2">blue</a>
<a href="#/path3">green</a>
<script>
class Router
{
constructor()
{
this.routes = {};
}
//将hashchange事件绑定到refresh()函数上
init()
{
window.addEventListener("hashchange", this.refresh.bind(this), false);
}
//注册路由和对应的回调函数
registerRoute(path, callback)
{
this.routes[path] = callback || function () {};
}
//读取当前的hash路径,根据已注册的路由和回调函数,更新页面
refresh()
{
let currentURL = location.hash.slice(1);
this.routes[currentURL]();
}
}
function changeElementColor(element, color)
{
element.style.backgroundColor = color;
}
window.onload = function ()
{
let div = document.querySelector("#app");
window.router = new Router();
window.router.init();
window.router.registerRoute("/path1", function ()
{
changeElementColor(div, "red");
});
window.router.registerRoute("/path2", function ()
{
changeElementColor(div, "blue");
});
window.router.registerRoute("/path3", function ()
{
changeElementColor(div, "green");
});
};
</script>
</body>
具体见HTML5相关章节。这个方法有个缺点,用户使用浏览器的前进
、后退
功能,浏览器会向服务器发起新的请求,服务器需要据此进行配置,还不如上面用井号方便。