LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

你点的“刷新”是假刷新?前端路由的瞒天过海术

zhenglin
2026年8月6日 15:11 本文热度 35

导读

为什么单页应用切换页面时,浏览器没有真正刷新?地址栏变了,页面却没白一下?今天我们来拆穿前端路由的“魔术”——它根本没去服务器要新页面,而是自己偷偷换了内容。看完这篇,你也能实现一个自己的前端路由。

前言

你有没有注意过,现在很多网站(比如知乎、B站、Github)点开一个新页面,地址栏变了,但页面没有那种“白屏-加载-闪现”的过程,而是瞬间切换内容。这就像你走进一家餐厅,菜单上写着“换桌”,你以为换了个房间,结果服务员只是把你桌上的桌布换了。

这就是前端路由干的“好事”。它让页面看起来跳转了,实际上只是JS在背后偷偷换了DOM,地址栏的变化也是骗你的。今天我们就来揭开这个魔术的奥秘,顺便自己写一个简单的路由。

一、什么是前端路由?

传统网站,点击链接会向服务器请求一个新HTML,浏览器刷新整个页面。这叫后端路由

单页应用(SPA)里,所有页面逻辑都在一个HTML里。切换“页面”时,不会请求新HTML,而是JS擦掉旧内容,画上新内容。同时,通过某种手段改变浏览器的地址栏URL,让用户感觉像换了个页面。这就是前端路由

前端路由的实现依赖两个“戏法”:

  • 改变URL但不刷新页面

  • 监听URL变化并渲染对应组件


二、Hash模式:带#号的“假跳转”

早期前端路由用的是hash(也就是URL里#后面的部分)。改变#后的值,不会触发页面刷新,也不会向服务器发请求。浏览器自己会记录历史(前进后退可用)。

// 改变hash

window.location.hash = 'home';


// 监听hash变化

window.addEventListener('hashchange', () => {

  const hash = window.location.hash.slice(1); // 去掉#

  renderPage(hash);

});


比如https://example.com/#/home,你改成#/about,页面不会刷新,但hashchange事件会触发,你可以在回调里根据hash渲染不同内容。

优点:兼容性好,IE也能用。
缺点:URL有个丑陋的#;服务端无法捕获#后面的内容(因为#之后的部分不会发到服务器)。

三、History模式:看起来像真的

HTML5新增了pushStatereplaceState,可以改变URL路径,同样不刷新页面。加上popstate事件监听,就能实现干净的路由(没有#)。


// 改变URL(添加一条历史记录)

history.pushState({ page: 'home' }, 'Home', '/home');


// 替换当前历史记录(不新增)

history.replaceState({ page: 'about' }, 'About', '/about');


// 监听前进后退

window.addEventListener('popstate', (event) => {

  const state = event.state; // pushState时传的数据

  renderPage(location.pathname);

});

优点:URL干净,像真实多页面。

缺点:需要服务端配合——因为刷新页面时,浏览器会按真实路径请求服务器,如果服务器没配置,会404。解决方案:所有路由都返回同一个HTML(即index.html)。

四、手写一个迷你前端路由

我们来实现一个最简单的Hash路由,包含三个“页面”:首页、关于、404。

<nav>

  <a href="#/home">首页</a>

  <a href="#/about">关于</a>

  <a href="#/nothing">不存在</a>

</nav>

<div id="app">内容会变</div>

function renderPage(path) {

  const app = document.getElementById('app');

  if (path === '/home') {

    app.innerHTML = '<h2>🏠 首页</h2><p>欢迎来到我的网站</p>';

  } else if (path === '/about') {

    app.innerHTML = '<h2>📖 关于</h2><p>这是一个前端路由演示</p>';

  } else {

    app.innerHTML = '<h2>❌ 404</h2><p>页面不存在</p>';

  }

}


// 监听hash变化

window.addEventListener('hashchange', () => {

  const hash = window.location.hash.slice(1); // 去掉#

  renderPage(hash || '/home');

});


// 页面加载时执行一次

window.addEventListener('load', () => {

  const hash = window.location.hash.slice(1);

  renderPage(hash || '/home');

});

就这么几行,你已经实现了一个前端路由。当然,实际框架里的路由更复杂(嵌套路由、动态参数、路由守卫等),但核心原理就是监听URL变化 + 渲染对应组件。

五、前端路由与后端路由的区别

特性后端路由前端路由
请求方式每次跳转都请求服务器不请求服务器(JS切换内容)
刷新页面会重新下载HTML会刷新但需要服务端配合(history模式)
首屏加载只加载当前页面通常要加载所有JS(可代码分割)
用户体验有白屏、闪烁切换流畅
SEO友好较差(需SSR或预渲染)

六、常见坑点与解决方案

1. History模式刷新404

配置Nginx将所有路由指向index.html:

location / {

  try_files $uri $uri/ /index.html;

}

2. 路由跳转但页面不滚动

单页切换时,滚动条位置可能保留在上一个页面的位置。需要在路由变化后手动window.scrollTo(0, 0)

3. 动态路由参数

比如/user/:id,你需要从路径中提取id。可以用正则或简单分割:

function matchRoute(path, routePath) {

  const pathParts = path.split('/');

  const routeParts = routePath.split('/');

  if (pathParts.length !== routeParts.length) return null;

  const params = {};

  for (let i = 0; i < pathParts.length; i++) {

    if (routeParts[i].startsWith(':')) {

      params[routeParts[i].slice(1)] = pathParts[i];

    } else if (routeParts[i] !== pathParts[i]) {

      return null;

    }

  }

  return params;

}

七、总结

  • 前端路由让单页应用切换页面时不刷新,体验流畅。
  • Hash模式# + hashchange,兼容性好,但URL丑。
  • History模式pushState + popstate,URL干净,需服务端配合。

  • 原理很简单:监听URL变化 → 根据路径渲染不同内容。

  • 现代框架(React Router、Vue Router)都是在此基础上增强。

下次再看到地址栏变了但页面没白,你就可以自信地说:“哼,不过是在演我。”

如果你喜欢今天的“魔术揭秘”,点个赞让更多人看到。明天我们将聊聊Webpack的Loader和Plugin原理,从零理解构建工具的核心。我们明天见!


阅读原文:点击这里


该文章在 2026/8/6 15:11:24 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-1  粤公网安备44030602007207号