history 路由基础
单页应用(SPA)"页面不刷新、地址栏却变化"靠的是 history API 两个方法:history.pushState(状态, 标题, url) 往浏览记录里压入一条新地址并更新地址栏,页面本身不重载;replaceState() 作用相同但替换当前记录而非新增。配合 popstate 事件——用户点前进/后退时触发——就能搭出最小路由。
最小路由由三部分组成:路由表(路径 → 内容的映射)、拦截链接(给站内 a 的 click 调 preventDefault,改用 pushState 跳转 + 手动渲染)、监听 popstate(前进后退时按 location.pathname 重新渲染)。地址栏、浏览记录、页面内容三者就这样保持同步。
一个必须知道的局限:用户在 /about 上刷新页面或直接访问时,请求会发到服务器,而服务器上并没有这个路径,会 404。所以生产环境需要服务器兜底配置——把所有路径都回退到 index.html(Nginx 的 try_files、各类云平台的 rewrite 规则都是干这个的)。
本节要点pushState/replaceState 改地址栏不刷新页面,popstate 监听前进后退;路由 = 路由表 + 拦截 a 点击 + popstate 渲染;服务器需配置所有路径回退到 index.html。
HTML
<a href="/home" data-link>首页</a> <a href="/about" data-link>关于</a> <div id="view"></div> <script> // 路由表:路径 → 页面内容 var routes = { '/home': '欢迎来到首页', '/about': '这是关于页面' }; function render(path) { document.getElementById('view').textContent = routes[path] || '404 未找到'; } // 拦截站内链接:阻止刷新,改用 pushState 无感切换 document.querySelectorAll('a[data-link]').forEach(function (a) { a.addEventListener('click', function (e) { e.preventDefault(); history.pushState({}, '', a.href); // 地址栏变化,页面不重载 render(a.pathname); }); }); // 前进/后退按钮:按当前路径重新渲染 window.addEventListener('popstate', function () { render(location.pathname); }); render(location.pathname); // 首次进入也渲染 </script>
📚 推荐阅读
来自万象云档的免费在线书籍,点击封面直接阅读




