前端路由依靠history.pushState与hashchange实现,不依赖服务端跳转;核心为拦截URL变化并更新视图而不刷新页面,分history模式(需服务端fallback)和hash模式(天然兼容但URL不美观)。

前端路由靠的是 history.pushState 和 hashchange
前端路由不依赖服务端跳转,本质是用浏览器原生 API 拦截 URL 变化、更新视图,而不刷新页面。核心就两条路:history.pushState(配合 popstate 事件)和 location.hash(监听 hashchange 事件)。现代框架如 React Router、Vue Router 默认走 history 模式,但部署时若后端没配 fallback,会 404;hash 模式则天然兼容,URL 带 #,比如 /#/user/123,服务端完全不用管。
用原生 JS 写一个最小可用的 history 路由
不需要框架也能跑起来,关键是三件事:拦截链接点击、响应浏览器前进后退、匹配路径并渲染。注意 pushState 不触发 popstate,所以首次加载得手动匹配一次。
const routes = {
'/': () => document.getElementById('app').innerHTML = '首页',
'/about': () => document.getElementById('app').innerHTML = '关于页',
'/user/:id': (params) => document.getElementById('app').innerHTML = `用户 ${params.id}`
};
function route() {
const path = location.pathname;
for (const [pattern, handler] of Object.entries(routes)) {
const regex = new RegExp('^' + pattern.replace(/:(\w+)/g, '([^/]+)') + '$');
const match = path.match(regex);
if (match) {
return handler(match.slice(1));
}
}
document.getElementById('app').innerHTML = '404';
}
// 首次加载
route();
// 监听前进后退
window.addEventListener('popstate', route);
// 拦截 a 标签点击
document.addEventListener('click', e => {
if (e.target.tagName === 'A' && e.target.href.startsWith(location.origin)) {
e.preventDefault();
const path = new URL(e.target.href).pathname;
history.pushState({}, '', path);
route();
}
});
history 模式上线必须配服务端 fallback
否则用户直接访问 /user/123 会 404——因为请求真的发到了服务器,而静态资源服务器根本不知道这个路径该返回哪个 HTML。解决方法不是前端改代码,而是让后端(或 Nginx、Vercel、Netlify 等托管平台)把所有非资源请求都返回 index.html。
- Nginx:加
try_files $uri $uri/ /index.html;到 location 块里 - Vercel:在
vercel.json中配"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }] - 本地开发用 Webpack DevServer?设
historyApiFallback: true
漏掉这步,本地跑得好好的,一上线就白屏,非常典型。
立即学习“Java免费学习笔记(深入)”;
hash 模式为什么不用配服务端?
因为 # 及之后的内容根本不会发送给服务器,纯前端解析。例如访问 https://site.com/#/user/123,实际 HTTP 请求的 URL 是 https://site.com/,服务端只管返回 index.html 就行,剩下的全由前端用 location.hash 读取、hashchange 监听。
但代价是 URL 不够美观,SEO 友好度低(虽然现在 Google 能处理部分 hash URL),且无法使用 scrollRestoration 等新 API。真正要上线的中后台系统,history 模式仍是首选,只是别忘了 fallback 这道坎。











