# ✅ 解决 SPA 路由刷新 404 问题 ## 🐛 问题描述 **症状:** - 访问 `https://sports.rucky.cn/music-rhythm` 正常 - 刷新页面后出现 **404 Not Found** 错误 - 可能出现双斜杠:`https://sports.rucky.cn//music-rhythm` ## 🔍 问题原因 ### 1. SPA 路由原理 单页应用(SPA)的路由是由前端 JavaScript 控制的: ``` 首次访问 https://sports.rucky.cn ↓ 服务器返回 index.html ↓ Vue Router 加载,解析路由 ↓ 点击链接 /music-rhythm ↓ Vue Router 更新 URL(不刷新页面) ↓ 渲染 MusicRhythm 组件 ✅ ``` ### 2. 刷新页面时的问题 ``` 刷新 https://sports.rucky.cn/music-rhythm ↓ 浏览器向服务器请求 /music-rhythm ↓ 服务器找不到 music-rhythm 文件夹或文件 ↓ 返回 404 错误 ❌ ``` ## ✅ 解决方案 ### 方案 1:Nginx 配置(推荐) 已创建配置文件:`nginx.conf.example` **关键配置:** ```nginx location / { try_files $uri $uri/ /index.html; } ``` **含义:** 1. 先尝试访问实际文件 `$uri` 2. 如果不存在,尝试访问目录 `$uri/` 3. 如果还不存在,返回 `index.html` 4. 让 Vue Router 处理路由 **完整配置步骤:** 1. 打开 Nginx 配置文件: ```bash sudo nano /etc/nginx/sites-available/sports.rucky.cn ``` 2. 添加/修改配置: ```nginx server { listen 443 ssl http2; server_name sports.rucky.cn; root /var/www/sports.rucky.cn; index index.html; # 关键:SPA 路由支持 location / { try_files $uri $uri/ /index.html; } } ``` 3. 测试配置: ```bash sudo nginx -t ``` 4. 重启 Nginx: ```bash sudo systemctl restart nginx ``` ### 方案 2:Apache 配置 已创建配置文件:`public/.htaccess` **关键配置:** ```apache RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] ``` **使用方法:** 1. 确保 Apache 启用了 `mod_rewrite`: ```bash sudo a2enmod rewrite sudo systemctl restart apache2 ``` 2. `.htaccess` 文件会自动包含在构建中: ```bash npm run build # dist/public/.htaccess 会自动复制到 dist/ ``` 3. 部署时确保 `.htaccess` 文件在网站根目录 ### 方案 3:Vercel/Netlify(自动处理) 如果使用这些平台,已创建 `public/_redirects` 文件: ``` /* /index.html 200 ``` **Vercel:** 自动识别,无需额外配置 **Netlify:** 自动识别 `_redirects` 文件 ## 🔧 前端优化 ### 1. 路由配置已优化 ```typescript const router = createRouter({ history: createWebHistory('/'), // 明确指定 base path routes: [...], }) ``` ### 2. 避免双斜杠问题 确保路由跳转时使用规范路径: ```typescript // ✅ 正确 router.push({ name: 'MusicRhythm' }) router.push('/music-rhythm') // ❌ 避免 router.push('//music-rhythm') ``` ## 🧪 测试步骤 ### 本地测试 1. 构建生产版本: ```bash npm run build ``` 2. 使用本地服务器测试(模拟生产环境): ```bash # 安装 serve npm install -g serve # 运行(支持 SPA) serve -s dist # 或使用 http-server npm install -g http-server http-server dist -p 8080 --proxy http://localhost:8080? ``` 3. 测试路由: - 访问 `http://localhost:3000/` - 点击进入音乐律动页面 - **刷新页面**,应该正常显示,不会 404 ### 生产环境测试 1. 部署到服务器 2. 访问各个页面: - `https://sports.rucky.cn/` ✅ - `https://sports.rucky.cn/music-rhythm` ✅ - `https://sports.rucky.cn/callback` ✅ 3. 在每个页面刷新,都应该正常显示 ## 📋 检查清单 部署前确认: - [ ] ✅ 服务器配置了 fallback 到 index.html - [ ] ✅ 所有路由路径以 `/` 开头,没有双斜杠 - [ ] ✅ `vite.config.js` 没有错误的 `base` 配置 - [ ] ✅ 构建产物在正确的目录 - [ ] ✅ 测试了所有主要路由的刷新 ## 🔍 调试技巧 ### 1. 检查服务器日志 **Nginx:** ```bash sudo tail -f /var/log/nginx/access.log sudo tail -f /var/log/nginx/error.log ``` **Apache:** ```bash sudo tail -f /var/log/apache2/access.log sudo tail -f /var/log/apache2/error.log ``` ### 2. 浏览器开发者工具 1. 打开 Network 标签 2. 刷新页面 3. 查看请求: - 应该看到请求 `/music-rhythm` - 服务器应该返回 `index.html`(状态码 200) - 而不是 404 ### 3. 测试 curl ```bash # 应该返回 index.html 内容 curl -I https://sports.rucky.cn/music-rhythm # 检查响应头 HTTP/1.1 200 OK Content-Type: text/html ``` ## 🎯 常见错误 ### 错误 1:双斜杠 **问题:** `https://sports.rucky.cn//music-rhythm` **原因:** 代码中拼接路径时多加了斜杠 **解决:** ```typescript // ❌ 错误 const url = origin + '/' + path // ✅ 正确 const url = origin + path // path 已经包含 / // 或 const url = new URL(path, origin).href ``` ### 错误 2:404 但本地正常 **问题:** 本地开发正常,生产环境 404 **原因:** Vite Dev Server 自动处理 SPA 路由,但生产服务器没有配置 **解决:** 按照上面的方案配置 Nginx/Apache ### 错误 3:子目录部署 **问题:** 部署在 `https://example.com/app/` 子目录下 **解决:** ```typescript // vite.config.js export default defineConfig({ base: '/app/', }) // router.ts const router = createRouter({ history: createWebHistory('/app/'), }) ``` ## 📚 相关文档 - [Vue Router HTML5 Mode](https://router.vuejs.org/guide/essentials/history-mode.html) - [Vite Static Deploy Guide](https://vitejs.dev/guide/static-deploy.html) - [Nginx try_files](http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files) ## ✅ 总结 **已完成:** 1. ✅ 优化前端路由配置 2. ✅ 创建 `.htaccess`(Apache) 3. ✅ 创建 `_redirects`(Vercel/Netlify) 4. ✅ 提供 `nginx.conf.example` **你需要做:** 1. 根据你使用的服务器(Nginx/Apache)配置 fallback 2. 重启服务器 3. 测试刷新功能 完成后,所有路由刷新都应该正常工作!🎉