修身养性,知行合一

  • 首页
  • 爱码
    • 系统
    • 数据库
    • JavaScript
    • CSharp
    • Python
  • 生活
    • 文化
    • 美食
  • 杂谈
  • 关于
修身养性,知行合一
码字,杂谈
  1. 首页
  2. 爱码
  3. 建站
  4. 正文

Github Pages SPA 重定向

2025年9月12日 17点热度 0人点赞 0条评论

最近更新了开源组件的文档,完全重写了一遍。其中大部分内容都是通过配置完成的,页面都是基本的渲染模板,通过 v-html 来渲染出来的具体内容。此时,就会出现:当需要展示一个跳转链接时,却发现使用不了 <RouterLink> 跳转组件,只能使用 <a> 标签的时候。但是 <a> 标签跳转的连接,却无法实现多非根目录下的内容的跳转,毕竟 url 的路径都是通过 SPA 提供的路由模式解决的。

跳转的方式

一般来说,我们遇到路径跳转问题,都有几种办法:

  • 将路由模式改为 HASH 模式,这样会显式的看到真正的路径
  • 如果部署在服务器上,可以通过修改 Nginx、Apache 等反向代理,来重定向到指定页面
  • 项目本身写一个 404 页面,然后跳转

由于文档部署在 Github Pages,并且它的很多页面都需要业内跳转,也就是它本身每个页面还需要hash定位跳转,所以前两种方式在这里并不合适,我们直接写一个 404 页面来实现跳转,只不过在写针对 Github Pages 的页面时,它给我们提供了一个非常好用的参数。

通过 404 页面跳转

1、Vite 配置打包

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

export default defineConfig({
  plugins: [vue()],
  base: '/gantt/',    // 根路径
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  },
  build: {
    outDir: 'dist',
    assetsDir: 'assets',
    // 确保 404.html 被正确复制到根目录
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        404: resolve(__dirname, 'public/404.html')   // 需要打到指定位置,替换原 404 页面
      }
    }
  }
})

2、创建自己的 404 页面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>页面重定向中...</title>
    <meta name="robots" content="noindex">
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f5f5f5;
        }
        .container {
            text-align: center;
            background: white;
            padding: 2rem;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .spinner {
            border: 4px solid #f3f3f3;
            border-top: 4px solid #3498db;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin: 20px auto;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
    </style>
    <script type="text/javascript">
        // GitHub Pages SPA 路由重定向解决方案
        (function() {
            var pathSegmentsToKeep = 1; // Github Pages 关键参数
            var l = window.location;

            // 构建重定向URL
            var redirect = l.protocol + '//' + l.hostname + 
                          (l.port ? ':' + l.port : '') +
                          l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + 
                          '/?/' +
                          l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
                          (l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
                          l.hash;

            console.log('Redirecting from:', l.href, 'to:', redirect);

            // 使用 replace 避免在浏览器历史中留下记录
            setTimeout(function() {
                l.replace(redirect);
            }, 0);
        })();
    </script>
</head>
<body>
    <div class="container">
        <h2>页面加载中...</h2>
        <div class="spinner"></div>
        <p>正在为您跳转到正确的页面,请稍候...</p>
        <!-- 这里需要写自己的首页路径,与 vite 中配置的 根路径 保持一致 -->
        <p>如果页面没有自动跳转,请 <a href="/gantt/">点击这里</a> 返回首页</p>
    </div>
</body>
</html>

Github Pages 的特殊参数

pathSegmentsToKeep 决定了在重定向 URL 中需要保留多少个路径段,这直接影响到重定向的正确性。

具体示例

假设你的 GitHub Pages 站点 URL 结构如下:

  • 情况1:仓库名部署 (pathSegmentsToKeep \= 1)

    原始 URL: https://username.github.io/gantt/docs/api
    分解:
    * Protocol: https://
    * Hostname: username.github.io
    * Path segments: ['', 'gantt', 'docs', 'api']
    * 保留段数: 1 (即保留 'gantt')

    重定向后的 URL:

    https://username.github.io/gantt/?/docs/api
  • 情况2:用户主页部署 (pathSegmentsToKeep \= 0)

    原始 URL: https://username.github.io/docs/api
    分解:
    * Protocol: https://
    * Hostname: username.github.io
    * Path segments: ['', 'docs', 'api']
    * 保留段数: 0 (不保留任何段)

    重定向后的 URL:

    https://username.github.io/?/docs/api

3、在 index.html 中添加路由恢复脚本

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <!-- GitHub Pages 路由恢复脚本 -->
    <script type="text/javascript">
        // 检查是否是从 404 页面重定向过来的
        (function(l) {
            if (l.search[1] === '/') {
                var decoded = l.search.slice(1).split('&').map(function(s) { 
                    return s.replace(/~and~/g, '&')
                }).join('?');

                var newUrl = l.pathname.slice(0, -1) + decoded + l.hash;
                console.log('Restoring route from:', l.href, 'to:', newUrl);

                window.history.replaceState(null, null, newUrl);
            }
        }(window.location));
    </script>
</head>

<body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
</body>

</html>

发布

最后就是发布到 Github Pages,如果使用了工作流,那么不要忘记打包时将 404.html 页面一并发布到项目中即可。

name: 部署文档
on:
  push:
    branches: [master]
    paths:
      - 'docs/**'

jobs:
  create-gh-pages:
    runs-on: ubuntu-latest
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
    steps:
      - name: 检查分支
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: xxx
        run: xxx

      - name: 创建发布目录并确保 404.html 在根目录
        run: |
          mkdir -p gh-pages/
          cp -r docs/dist/* gh-pages/
          # 确保 404.html 在根目录
          if [ -f "docs/public/404.html" ]; then
            cp docs/public/404.html gh-pages/404.html
          fi
          # 验证文件结构
          echo "Generated files:"
          ls -la gh-pages/
          if [ -f "gh-pages/404.html" ]; then
            echo "✅ 404.html found in root"
          else
            echo "❌ 404.html NOT found in root"
          fi
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: github 建站
最后更新:2025年9月12日

jeremyjone

这个人很懒,什么都没留下

打赏 点赞
< 上一篇

文章评论

取消回复

文章目录
  • 跳转的方式
  • 通过 404 页面跳转
    • 1、Vite 配置打包
    • 2、创建自己的 404 页面
    • Github Pages 的特殊参数
    • 3、在 index.html 中添加路由恢复脚本
    • 发布
最新 热点 随机
最新 热点 随机
Github Pages SPA 重定向 行间距引出的 DOCTYPE 怪异行为 写个小彩蛋 绘制一个可重用的线条阴影 node-sass 的安装 解决端口被占的问题
行间距引出的 DOCTYPE 怪异行为Github Pages SPA 重定向
IdentityServer4深入使用(二)-- 认证与授权(下) 2021就要过去了 双十一 京东养红包攻略 如何写一个组件级别的全局状态管理 JavaScript 之 canvas(二)-- 绘制基本图形 MySQL升级之路(5.6-8.0)

(っ•̀ω•́)っ✎⁾⁾ 开心每一天

COPYRIGHT © 2021 jeremyjone.com. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

京ICP备19012859号-1

京公网安备 11010802028585号