
本文介绍如何使用原生 JavaScript 实现类似 React Router 的动态、嵌套路由跳转,避免服务器 404 错误,核心是利用 URL 哈希(#)模式进行前端路由控制。
本文介绍如何使用原生 javascript 实现类似 react router 的动态、嵌套路由跳转,避免服务器 404 错误,核心是利用 url 哈希(`#`)模式进行前端路由控制。
在纯 HTML + JavaScript 环境中实现“动态嵌套路由”,关键在于理解浏览器导航机制与服务器请求的区别:当你执行 window.location.replace('/123'),浏览器会向服务器发起对 /index.html/123(或根路径下的 /123)的真实资源请求——而静态服务器(如本地 file:// 或简易 HTTP 服务)通常不提供该路径的 HTML 文件,因此返回 Cannot GET /123 错误。
✅ 正确方案是采用 Hash-based Routing(哈希路由):所有路由变更仅影响 URL 中 # 后的部分,浏览器不会向服务器发起新请求,完全由前端 JS 解析并响应。
✅ 推荐实现方式(含完整示例)
HTML(保持简洁):
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vanilla JS Router</title><nav><button onclick="navigateTo('/home')">Home</button>
<button onclick="navigateTo('/about')">About</button>
<button onclick="navigateTo('/user/123')">User #123</button>
<button onclick="navigateTo('/post/456/comments')">Post Comments</button>
</nav><main id="view">Loading...</main><script src="router.js"></script>
JavaScript(router.js)——轻量级哈希路由控制器:
// 路由映射表(可动态扩展)
const routes = {
'/home': () => '<h2>Welcome Home!</h2><p>This is the homepage.</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4093" title="在SEO发布前,从路由清单生成XML网站地图和robots.txt"><img
src="https://img.php.cn/upload/skill/000/000/081/178990212190155.jpg" alt="在SEO发布前,从路由清单生成XML网站地图和robots.txt" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill4093" title="在SEO发布前,从路由清单生成XML网站地图和robots.txt" class="overflowclass">在SEO发布前,从路由清单生成XML网站地图和robots.txt</a>
<p class="overflowclass">当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。</p>
</div>
<a rel="nofollow" href="/xiazai/skill4093" title="在SEO发布前,从路由清单生成XML网站地图和robots.txt" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>',
'/about': () => '<h2>About Us</h2><p>We build awesome vanilla apps.</p>',
'/user/:id': (params) => `<h2>User Profile</h2><p>ID: ${params.id}</p>`,
'/post/:id/comments': (params) => `<h2>Comments for Post #${params.id}</h2>
- Great post!
- Thanks for sharing.
The requested page does not exist.
'; } // 导航函数(推荐统一入口) function navigateTo(path) { window.location.hash = path; } // 初始化 & 监听哈希变化 document.addEventListener('DOMContentLoaded', () => { // 首次加载渲染 renderView(); // 监听后续哈希变化(前进/后退/手动修改) window.addEventListener('hashchange', renderView); });⚠️ 注意事项与最佳实践
- 不要用 window.location.replace(...) 拼接完整 URL:这会触发真实页面跳转,导致 404;应始终操作 location.hash。
- 服务端无需配置:哈希路由完全在前端运行,适合 GitHub Pages、Vercel Static、本地测试等无后端场景。
- SEO 限制:传统哈希路由对搜索引擎不友好(现代爬虫虽可执行 JS,但仍建议生产环境优先考虑 HTML5 History API + 服务端 fallback)。
- 增强体验:可结合 history.pushState() 实现无哈希的干净 URL(需配合服务端配置 fallback index.html),但本方案聚焦零依赖、开箱即用。
通过以上结构,你已拥有一套可扩展、支持嵌套参数(如 /user/123 → /user/:id)、无需构建工具的原生路由系统——真正“动态”且“嵌套”,同时彻底规避 Cannot GET 错误。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










