手动写过路由的人,一定对这个流程不陌生:先调用history.pushState,再绑一个popstate监听器,接着发现pushState根本不会触发popstate事件,只好把URL变更的逻辑再单独补一遍,然后手动接管页面里的每一个链接点击,最后崩溃认输,转而投靠某个框架的路由方案。
这一切的根源在于,History API从来就不是为单页应用设计的,它只是一个为多页面导航打的薄补丁。过去十多年,我们一直在给这个补丁打补丁。
![]()
现在终于有了正解——Navigation API。到2026年初,这个API已经不再是实验性玩具,而是可以放心落地的东西了。2026年1月,它正式进入“Baseline Newly Available”阶段,Chrome、Edge、Firefox 147和Safari 26.2都已支持,意味着一个专门为客户端路由设计的集中式接口,现在已经能在桌面端和移动端的所有主流引擎上稳定运行。
Navigation API的核心思想很直接:在全局的navigation对象上,只靠一个navigate事件,就能处理所有类型的导航——链接点击、表单提交、程序化跳转,甚至是浏览器的前进/后退按钮。以前你需要把点击处理器散落在整个应用里,还总担心漏掉哪一个,现在路由逻辑可以集中到一个地方,干净利落。
来看一段关键代码。监听navigate事件,然后判断是不是自己该插手的导航:
navigation.addEventListener("navigate", (navigateEvent) => {// 让浏览器处理那些我们不该碰的导航。if (shouldNotIntercept(navigateEvent)) return;const url = new URL(navigateEvent.destination.url);if (url.pathname.startsWith("/articles/")) {navigateEvent.intercept({async handler() {renderPlaceholder();const content = await getArticleContent(url.pathname);renderArticle(content);},});
这里的intercept({ handler })是整个API的精髓。它相当于明确告诉浏览器:“这个导航我接管了,这是同文档更新,可能会花一点时间。”因为handler返回的是一个promise——async函数会自动返回promise——所以浏览器能确切知道这个导航什么时候开始、什么时候完成、什么时候失败。这可是平台真正理解了的语义。就因为这个明确的语义,Chrome在进行异步路由切换时,会直接展示原生的加载指示器,并激活停止按钮。这些可访问性层面的收益,是过去靠手动操作history对象根本拿不到的。
在旧API下,所有上下文信息都得自己费力去还原,而navigate事件直接把这些信息送上门了。事件对象navigateEvent里自带了各种判断依据,一个轻巧的守护函数就能帮你过滤掉那些根本不该拦截的导航:
function shouldNotIntercept(navigateEvent) {return (!navigateEvent.canIntercept || // 跨域等不可拦截的情况navigateEvent.hashChange || // 仅锚点跳转navigateEvent.downloadRequest !== null || // 下载请求navigateEvent.formData !== null // 表单提交(你可能想让浏览器正常处理)}
这个守护函数帮你避开了跨域导航、锚点跳转、下载请求和表单提交,确保你只拦截自己真正负责的同源路径更新。把路由逻辑集中在一处之后,整个应用的架构都会变得清爽:不再需要一个个组件去关心自己是否拦截了链接,不再需要手动维护一套脆弱的URL同步机制。
Navigation API的出现,等于把前端路由从手动挡升级到了自动挡。一个集中式接口,一场10年的弯路,终于在2026年被一个API终结。如果你的项目还在用history.pushState打补丁,是时候换条路走了。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.