Vue Router的History模式与Hash模式在部署时的区别
Vue Router 提供了两种路由模式:Hash 模式和 History 模式。这两种模式在浏览器端的表现不同,在生产环境部署时的要求更是天差地别。理解两者的区别并正确配置服务器,是避免应用上线后出现“404 Not Found”或“白屏”问题的关键。
核心差异对比
Hash 模式和 History 模式最直观的区别在于 URL 的形态,以及这对服务器行为产生的直接影响。
| 特性 | Hash 模式 | History 模式 |
|---|---|---|
| URL 形态 | 带有 # 号,如 example.com/#/user |
也就是传统的 URL,如 example.com/user |
| 原理 | 利用 window.location.hash 变化,不触发 HTTP 请求 |
利用 HTML5 History API,需要服务器配合 |
| 部署难度 | 低,无需特殊服务器配置,直接上传即可 | 高,必须配置服务器“重写”规则 |
| 用户体验 | URL 较长,带有特殊符号,看起来不专业 | URL 简洁美观,SEO 友好 |
| 刷新页面行为 | 仅请求根目录,页面正常 | 向服务器请求子路径(如 /user),若无配置则报 404 |
Hash 模式:无需配置的“零门槛”部署
Hash 模式之所以被称为“零门槛”,是因为 URL 中 # 后面的内容永远不会被包含在 HTTP 请求中。这意味着无论用户访问 /#/home 还是 /#/detail/123,服务器接收到的永远只是对根目录 / 的请求。
部署步骤
-
构建 Vue 项目。
在终端运行npm run build,生成dist目录。 -
上传 静态文件。
将dist目录下的所有文件(index.html,css,js,img等)直接上传至服务器的 Web 根目录(如 Nginx 的/usr/share/nginx/html或 Apache 的/var/www/html)。 -
访问 测试。
直接在浏览器输入域名即可,任何页面刷新都不会出现 404 错误。
History 模式:必须配置的“高颜值”方案
History 模式去掉了丑陋的 #,让 URL 看起来像标准的多页应用。但这带来了一个严重的问题:当用户直接访问 example.com/user 或刷新该页面时,浏览器会向服务器请求 /user 这个路径。如果服务器找不到对应的物理文件,就会返回 404 错误。
为了解决这个问题,必须配置服务器,实现“单页应用(SPA)回退”:即对于任何不存在的路径请求,服务器都应该返回 index.html,然后由 Vue Router 接管渲染。
以下流程图直观展示了 History 模式下,正确配置与未配置服务器的请求处理差异:
Nginx 服务器配置步骤
Nginx 是目前最流行的前端静态资源服务器,配置 History 模式非常简单。
-
打开 Nginx 配置文件。
通常位于/etc/nginx/nginx.conf或/etc/nginx/sites-available/default。 -
找到
server块下的location /配置项。 -
修改
try_files指令。
确保该行包含$uri $uri/ /index.html,这表示如果找不到对应文件,就回退到index.html。
location / {
root /usr/share/nginx/html; # 你的 dist 目录路径
index index.html index.htm;
# 核心配置:尝试寻找文件($uri),若不存在则寻找目录($uri/),
# 若仍不存在,则返回 index.html,内部交给 Vue Router 处理
try_files $uri $uri/ /index.html;
}
-
检查 配置语法。
运行命令nginx -t确保配置无误。 -
重启 Nginx 服务。
运行命令nginx -s reload使配置生效。
Apache 服务器配置步骤
如果你的后端服务运行在 Apache 上,需要开启重写模块并配置 .htaccess 文件。
-
开启
mod_rewrite模块。
运行命令a2enmod rewrite。 -
创建
.htaccess文件。
在你的dist目录根目录下新建一个名为.htaccess的文件。 -
写入 重写规则。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
```
4. **重启** Apache 服务。
运行命令 `systemctl restart apache2`。
### Node.js (Express) 服务器配置步骤
在 Node.js 环境中,通常使用 `connect-history-api-fallback` 中间件来处理。
1. **安装** 中间件依赖。
在项目根目录运行 `npm install connect-history-api-fallback --save`。
2. **引入** 并 **使用** 中间件。
在 `app.js` 或入口文件中,务必在 `app.use(express.static(...))` **之前** 引入该中间件。
```javascript
const express = require('express');
const history = require('connect-history-api-fallback');
const app = express();
// 核心配置:必须在静态资源服务之前使用
app.use(history());
// 提供静态资源服务 (dist 目录)
app.use(express.static(__dirname + '/dist'));
app.listen(3000, () => {
console.log('Server running on port 3000');
});
```
---
## 常见问题与排查
### 后端 API 接口 404
如果配置了 History 模式的回退规则,可能会导致所有的请求(包括 API 请求)都被重定向到 `index.html`。
1. **排查** API 请求路径。
确保 API 请求的路径(如 `/api/getData`)与前端路由路径(如 `/user`)有明显区分,例如加上 `/api` 前缀。
2. **修改** 服务器配置。
在 Nginx 中,需要排除 API 路径的转发。
```nginx
location /api {
proxy_pass http://backend_server; # 转发到后端真实接口
}
location / {
try_files $uri $uri/ /index.html; # 前端路由回退
}
页面刷新后样式丢失或资源加载 404
这通常是因为构建时设置了 publicPath 为相对路径,或者服务器无法正确解析相对路径。
- 检查
vue.config.js(或vite.config.js)。
将publicPath设置为/(绝对路径)。
module.exports = {
publicPath: '/', // 确保这是根路径,而不是 './'
// ...
}
- 重新构建 并 上传 文件。

暂无评论,快来抢沙发吧!