一句话总结
- Hash 模式 :利用 URL 中
# 后的内容变化实现前端路由,不触发页面刷新,兼容性好。
- History 模式 :基于 HTML5 的
history.pushState() 和 popstate 事件,URL 更干净,但需要服务端配合。
一、Hash 模式(默认模式)
1. 基本形式
bash
复制代码
https://example.com/#/user/profile
↑
hash 部分
2. 工作原理
- 核心机制 :监听
window.onhashchange 事件。
- 当用户点击链接或调用
router.push() 时,Vue Router 修改 location.hash(如 #/home → #/about)。
- 浏览器不会向服务器发起请求 ,因为
# 及其后的内容不会发送给服务器。
- 页面 URL 改变但不刷新,前端根据新的 hash 值匹配路由并渲染对应组件。
3. 特点
| 优点 |
缺点 |
| ✅ 兼容性极好(IE8+ 支持) |
❌ URL 中带有 #,不够美观 |
| ✅ 无需服务端配置 |
❌ SEO 友好性略差(部分爬虫可能忽略 hash) |
| ✅ 天然避免 404 问题 |
❌ 不符合传统 URL 语义 |
4. 示例代码(Vue Router 配置)
arduino
复制代码
const router = new VueRouter({
mode: 'hash', // 默认值,可省略
routes: [...]
});
二、History 模式(推荐用于现代项目)
1. 基本形式
arduino
复制代码
https://example.com/user/profile
URL 看起来和传统多页应用一致,无 # 符号。
2. 工作原理
-
history.pushState(state, title, url):在不刷新页面的情况下修改浏览器历史记录和 URL。
history.replaceState(...):替换当前历史记录。
window.onpopstate:监听浏览器前进/后退操作(如点击 ← → 按钮)。
-
- 用户访问
/home → 前端加载,Vue Router 渲染 Home 组件。
- 点击"关于"链接 → 调用
router.push('/about') → 执行 history.pushState(null, '', '/about')。
- URL 变为
https://example.com/about,页面不刷新,About 组件被渲染。
- 用户刷新页面 → 浏览器向服务器请求
/about 资源。
3. 关键问题:刷新 404
- 原因 :服务器收到
/about 请求时,若未配置,会尝试查找物理路径下的 about.html 或目录,找不到则返回 404。
- 解决方案 :服务端需配置"兜底路由" ,将所有前端路由请求重定向到
index.html。
Nginx 配置示例:
bash
复制代码
location / {
try_files $uri $uri/ /index.html;
}
4. 特点
| 优点 |
缺点 |
| ✅ URL 简洁美观,符合 REST 风格 |
❌ 需要服务端支持(部署配置) |
| ✅ 更好的 SEO(主流爬虫已支持) |
❌ 在纯静态托管(如 GitHub Pages)中需额外处理 |
| ✅ 用户体验更接近原生 Web |
❌ 旧浏览器(IE9 以下)不支持 |
5. 示例代码(Vue Router 配置)
ini
复制代码
const router = new VueRouter({
mode: 'history',
routes: [...]
});
🔁 三、对比总结
| 特性 |
Hash 模式 |
History 模式 |
| URL 样式 |
example.com/#/path |
example.com/path |
| 刷新是否 404 |
❌ 不会(# 后内容不发给服务器) |
✅ 会(需服务端配置兜底) |
| 浏览器兼容性 |
IE8+ |
IE10+(HTML5 History API) |
| 服务端要求 |
无 |
必须配置 fallback 到 index.html |
| SEO 友好性 |
一般 |
较好(现代爬虫支持) |
| 使用场景 |
快速原型、老旧环境、无服务端控制权 |
正式项目、追求用户体验、有运维支持 |
💡 最佳实践建议
- 开发阶段 :两种模式均可,推荐
history 提前暴露部署问题。
- 生产部署:
-
- 若使用 Nginx/Apache/Caddy → 优先选
history + 配置 fallback。
补充知识
- 为什么 hash 不发给服务器?
根据 HTTP 规范,URL 中 #fragment 部分仅用于客户端定位(如锚点),不会包含在 HTTP 请求中。
- History API 安全限制
pushState 只能修改同源下的路径,不能跨域篡改 URL,保障了安全性。