|
1 | | -# Avatar 本地资源加载说明 |
| 1 | +# GitHub Pages React Router 支持文档 |
| 2 | + |
| 3 | +## 概述 |
| 4 | + |
| 5 | +GitHub Pages 支持 React Router,但需要特殊配置来处理客户端路由。本项目已配置完成,支持以下路由: |
| 6 | + |
| 7 | +- `/` - 友链列表页(原首页内容) |
| 8 | +- `/home` - 主页 |
| 9 | +- `/about` - 关于页面 |
| 10 | + |
| 11 | +## 实现原理 |
| 12 | + |
| 13 | +### 问题 |
| 14 | +GitHub Pages 是静态文件托管服务,当用户直接访问 `/home` 或 `/about` 时,服务器会寻找对应的物理文件,但这些路由是由 React Router 在客户端处理的,不存在实际的文件,因此会返回 404 错误。 |
| 15 | + |
| 16 | +### 解决方案 |
| 17 | +使用 SPA(Single Page Application)GitHub Pages 解决方案: |
| 18 | + |
| 19 | +1. **404.html 重定向**: 创建 `public/404.html` 文件,将所有 404 请求重定向到主应用 |
| 20 | +2. **URL 参数处理**: 在 `index.html` 中添加脚本处理重定向的 URL 参数 |
| 21 | +3. **React Router 配置**: 配置 BrowserRouter 和路由规则 |
| 22 | + |
| 23 | +## 配置文件 |
| 24 | + |
| 25 | +### public/404.html |
| 26 | +```html |
| 27 | +<!DOCTYPE html> |
| 28 | +<html> |
| 29 | + <head> |
| 30 | + <meta charset="utf-8"> |
| 31 | + <title>Friends</title> |
| 32 | + <script type="text/javascript"> |
| 33 | + // Single Page Apps for GitHub Pages |
| 34 | + var pathSegmentsToKeep = 0; |
| 35 | + var l = window.location; |
| 36 | + l.replace( |
| 37 | + l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') + |
| 38 | + l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + '/?/' + |
| 39 | + l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') + |
| 40 | + (l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') + |
| 41 | + l.hash |
| 42 | + ); |
| 43 | + </script> |
| 44 | + </head> |
| 45 | + <body> |
| 46 | + </body> |
| 47 | +</html> |
| 48 | +``` |
| 49 | + |
| 50 | +### index.html 中的处理脚本 |
| 51 | +```javascript |
| 52 | +<script type="text/javascript"> |
| 53 | + (function(l) { |
| 54 | + if (l.search[1] === '/' ) { |
| 55 | + var decoded = l.search.slice(1).split('&').map(function(s) { |
| 56 | + return s.replace(/~and~/g, '&') |
| 57 | + }).join('?'); |
| 58 | + window.history.replaceState(null, null, |
| 59 | + l.pathname.slice(0, -1) + decoded + l.hash |
| 60 | + ); |
| 61 | + } |
| 62 | + }(window.location)) |
| 63 | +</script> |
| 64 | +``` |
| 65 | + |
| 66 | +## 路由组件 |
| 67 | + |
| 68 | +### src/components/Home.tsx |
| 69 | +主页组件,展示欢迎信息 |
| 70 | + |
| 71 | +### src/components/About.tsx |
| 72 | +关于页面组件,展示网站介绍信息 |
| 73 | + |
| 74 | +## 导航 |
| 75 | +应用包含顶部导航栏,支持在不同页面间跳转: |
| 76 | +- 友链列表 |
| 77 | +- 主页 |
| 78 | +- 关于 |
| 79 | + |
| 80 | +## 部署 |
| 81 | +运行 `npm run deploy` 命令会: |
| 82 | +1. 构建应用 |
| 83 | +2. 复制 CNAME 文件到 dist 目录 |
| 84 | +3. 复制 404.html 文件到 dist 目录 |
| 85 | + |
| 86 | +## 注意事项 |
| 87 | +1. 所有路由在本地开发和 GitHub Pages 上都能正常工作 |
| 88 | +2. 直接访问路由 URL(如 https://yoursite.github.io/home)会正确跳转 |
| 89 | +3. 浏览器前进/后退按钮正常工作 |
| 90 | +4. 页面刷新不会出现 404 错误 |
| 91 | + |
| 92 | +## 技术栈 |
| 93 | +- React 19 |
| 94 | +- React Router 7 |
| 95 | +- Vite |
| 96 | +- TypeScript |
| 97 | +- Tailwind CSS |
| 98 | +- Radix UI |
2 | 99 |
|
3 | 100 | 在 `blogs.json` 中,有的条目的 `avatar` 字段是完整的远程 URL(以 https:// 开头),有的条目使用了相对文件名,比如 `avatar.png`。 |
4 | 101 |
|
|
0 commit comments