Files
newToy/FIX_404_PROBLEM.md
2025-11-23 23:55:10 +08:00

6.0 KiB
Raw Permalink Blame History

解决 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 错误 ❌

解决方案

方案 1Nginx 配置(推荐)

已创建配置文件:nginx.conf.example

关键配置:

location / {
    try_files $uri $uri/ /index.html;
}

含义:

  1. 先尝试访问实际文件 $uri
  2. 如果不存在,尝试访问目录 $uri/
  3. 如果还不存在,返回 index.html
  4. 让 Vue Router 处理路由

完整配置步骤:

  1. 打开 Nginx 配置文件:
sudo nano /etc/nginx/sites-available/sports.rucky.cn
  1. 添加/修改配置:
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;
    }
}
  1. 测试配置:
sudo nginx -t
  1. 重启 Nginx
sudo systemctl restart nginx

方案 2Apache 配置

已创建配置文件:public/.htaccess

关键配置:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

使用方法:

  1. 确保 Apache 启用了 mod_rewrite
sudo a2enmod rewrite
sudo systemctl restart apache2
  1. .htaccess 文件会自动包含在构建中:
npm run build
# dist/public/.htaccess 会自动复制到 dist/
  1. 部署时确保 .htaccess 文件在网站根目录

方案 3Vercel/Netlify自动处理

如果使用这些平台,已创建 public/_redirects 文件:

/*    /index.html   200

Vercel 自动识别,无需额外配置 Netlify 自动识别 _redirects 文件

🔧 前端优化

1. 路由配置已优化

const router = createRouter({
  history: createWebHistory('/'), // 明确指定 base path
  routes: [...],
})

2. 避免双斜杠问题

确保路由跳转时使用规范路径:

// ✅ 正确
router.push({ name: 'MusicRhythm' })
router.push('/music-rhythm')

// ❌ 避免
router.push('//music-rhythm')

🧪 测试步骤

本地测试

  1. 构建生产版本:
npm run build
  1. 使用本地服务器测试(模拟生产环境):
# 安装 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?
  1. 测试路由:
    • 访问 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

sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

Apache

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

# 应该返回 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

原因: 代码中拼接路径时多加了斜杠

解决:

// ❌ 错误
const url = origin + '/' + path

// ✅ 正确
const url = origin + path  // path 已经包含 /
// 或
const url = new URL(path, origin).href

错误 2404 但本地正常

问题: 本地开发正常,生产环境 404

原因: Vite Dev Server 自动处理 SPA 路由,但生产服务器没有配置

解决: 按照上面的方案配置 Nginx/Apache

错误 3子目录部署

问题: 部署在 https://example.com/app/ 子目录下

解决:

// vite.config.js
export default defineConfig({
  base: '/app/',
})

// router.ts
const router = createRouter({
  history: createWebHistory('/app/'),
})

📚 相关文档

总结

已完成:

  1. 优化前端路由配置
  2. 创建 .htaccessApache
  3. 创建 _redirectsVercel/Netlify
  4. 提供 nginx.conf.example

你需要做:

  1. 根据你使用的服务器Nginx/Apache配置 fallback
  2. 重启服务器
  3. 测试刷新功能

完成后,所有路由刷新都应该正常工作!🎉