做过后端开发,尤其是使用过 Django、Express 等框架的开发者,对“路由”应该并不陌生。以 WordPress 为例,当网站使用固定链接后,用户访问的 URL 可能是:
/article/example/
也可能是:
/category/javascript/
虽然访问的地址不同,但在传统 WordPress 架构中,请求最终会经过入口程序进行解析,再根据 URL 判断当前请求对应文章、分类、标签或其他页面,然后执行相应的程序逻辑。
简单来说,路由就是根据一个地址或请求,决定由哪个程序或逻辑来处理它。
什么是前端路由?
后端路由通常发生在服务器端,而前端路由则发生在浏览器中。
传统网站切换页面时:
- 用户点击链接;
- 浏览器向服务器发送新的请求;
- 服务器返回新的 HTML;
- 浏览器重新加载页面。
而单页应用(SPA)通常只有一个主要的 HTML 页面。当用户进行页面切换时,浏览器并不一定重新加载整个页面,而是由 JavaScript 根据当前 URL 的变化,更新页面中的部分内容。
例如:
https://example.com/#/news
和:
https://example.com/#/time
虽然它们实际上仍然是同一个 HTML 页面,但前端程序可以根据 # 后面的内容,执行不同的逻辑。
这就是早期常见的 Hash 路由。Hash 路由通过监听 URL 中 # 后面的片段变化来切换页面状态,不需要服务器额外配置,因此非常适合早期的单页应用和纯静态站点。
director.js 是什么?
director.js 是一个轻量级的 JavaScript 路由库。它的主要作用,就是将不同的 URL 路径与对应的 JavaScript 函数关联起来。例如:
var route = {
"/time": showTime,
"/news": showNews
};
var router = Router(route);
router.init();当 URL 变成:
#/time
时,执行 showTime()。
当 URL 变成:
#/news
时,则执行 showNews()。也就是说:
URL 负责描述当前状态,路由负责解析 URL,回调函数负责执行具体操作。
这也是前端路由最基本的工作方式。
一个简单的示例
假设现在要实现一个简单的 Web 桌面。
页面中有两个应用:
- 查看当前时间;
- 打开新闻页面。
HTML 可以这样写:
<ahref="#/time">当前时间</a>
<ahref="#/news">新闻</a>
然后定义路由:
var routes = {
"/time": showTime,
"/news": showNews
};
var router = Router(routes);
router.init();接下来分别定义对应的处理函数:
function showTime() {
var now = new Date();
alert(
now.getFullYear() + "年" +
(now.getMonth() + 1) + "月" +
now.getDate() + "日 " +
now.getHours() + ":" +
now.getMinutes() + ":" +
now.getSeconds()
);
}当用户点击:
#/time
时,director.js 会匹配:
"/time": showTime
然后执行 showTime()。整个过程中,浏览器并不会重新加载整个页面。
一个路由可以执行多个操作
director.js 也可以让一个路由对应多个回调函数。
例如:
var routes = {
"/news": [showWindow, loadNews]
};当访问:
#/news
时,可以先执行:
showWindow();
创建一个窗口,然后再执行:
loadNews();
加载具体的数据。这种方式比较适合把一个操作拆分成多个步骤,例如:
路由变化
↓
创建页面
↓
加载数据
↓
更新界面
前端路由的意义
前端路由的价值并不仅仅是“不刷新页面”。它更重要的作用是让 URL 与应用状态建立对应关系。例如:
#/article/100
表示当前正在查看某篇文章。
#/user/profile
表示当前正在查看用户资料。
#/settings
表示当前进入设置页面。
这样用户不仅可以点击页面进行导航,还可以:
- 使用浏览器前进和后退;
- 收藏当前页面;
- 直接复制 URL 分享给其他人。
这也是现代 Web 应用中路由系统的重要作用。
director.js 对 SEO 有影响吗?
严格来说,不是 director.js 本身影响 SEO,而是纯客户端 Hash 路由的内容组织方式可能不适合传统内容型网站。
例如:
https://example.com/#/article/100
# 后面的内容属于 URL 的片段标识符。传统的 Hash 路由主要依赖客户端 JavaScript 来解析和渲染内容,而搜索引擎通常不会把 # 后面的部分当作独立页面路径处理。MDN 也将 Hash 路由视为一种较早期的 SPA 路由方案,并建议现代应用优先考虑 History API 等方式。
因此,如果你开发的是:
- 企业官网;
- 博客;
- 新闻网站;
- 内容型网站;
- 主要依赖自然搜索流量的网站;
一般不建议为了页面切换而把整个网站设计成纯 Hash 路由的单页应用。因为对于这类网站来说,每一篇文章、每一个分类页面都应该有独立且稳定的 URL,并且最好能够直接由服务器返回对应内容。而如果开发的是:
- 后台管理系统;
- Web 工具;
- 在线应用;
- 内部系统;
- 数据面板;
前端路由则非常适合。
现在的前端路由有什么变化?
这篇文章最初讨论的是 Hash 路由。现在来看,这种方式仍然可以使用,但已经不再是现代单页应用的主流方案。目前更常见的是使用:
history.pushState()
和:
window.addEventListener("popstate", ...)实现基于正常路径的前端路由,例如:
/article/100
而不是:
#/article/100
History API 可以在不重新加载整个页面的情况下修改浏览器地址和历史记录,并支持浏览器前进、后退等操作,是现代 SPA 路由的重要基础。因此,现在使用 React、Vue、Angular 等框架开发单页应用时,通常会直接使用各自生态中的路由方案。另外,浏览器平台近年还推出了 Navigation API,专门面向更复杂的 Web 应用导航场景,但实际项目是否采用,还需要考虑浏览器兼容性。
总结
director.js 可以帮助我们理解前端路由最基本的工作原理:
当 URL 发生变化时,路由系统解析当前地址,并执行对应的 JavaScript 逻辑,从而更新页面内容。
从早期的:
#/route
Hash 路由,到现在广泛使用的:
history.pushState()
前端路由的实现方式发生了很大的变化,但核心思想并没有改变:
根据 URL 的变化,控制应用的状态和界面。
director.js 虽然更适合作为理解早期前端路由机制的工具,但通过它学习路由注册、URL 匹配和回调执行,对于理解现代 SPA 路由依然很有帮助。
参考资料
- MDN:Hash 路由
- MDN:使用 History API
评论0
欢迎分享你的看法,也欢迎补充不同的实践经验。