重新加载发布到 Github 页面的 Vue 网站时出现 404

404 when reloading a Vue website published to Github pages

我已经在 christopherkade.github.io 的 master 分支中部署了我的 /dist 文件夹的内容,这已经成功部署了我的 website

但是当我使用导航栏(christopherkade.com/postschristopherkade.com/work)导航并重新加载页面时,我收到 Github 页错误:

404 File not found

请注意,我的路由是使用 Vue 路由器完成的,如下所示:

export default new Router({
  mode: 'history',
  routes: [    
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/work',
      name: 'Work',
      component: Work
    },
    {
      path: '/posts',
      name: 'Posts',
      component: Posts
    },
    { path: '*', component: Home }
  ]
})

我的项目是这样构建的:

build: {
    // Template for index.html
    index: path.resolve(__dirname, '../docs/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../docs'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',

    /**
     * Source Maps
     */

    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }

可能是什么导致了这个问题?

这实际上是因为您的浏览器向 christopherkade.com/posts URL 发出了不存在的请求(此路由在 Vue 应用程序 运行 中从 index.html 定义) .

如果您是 运行 您自己的服务器,您可能会将其配置为呈现任何请求 URI 的 index.html 页面,这样您的 Vue 应用程序将从任何路径加载并处理路由本身。

说到 GitHub 页面,您不能仅仅将它们配置为按照我描述的方式运行,但幸运的是,有一个使用自定义 404 页面的解决方法: https://github.com/rafrex/spa-github-pages

But when I navigate using the navbar (christopherkade.com/posts or christopherkade.com/work) and reload the page 404 File not found

让我解释一下为什么显示 404 File not found

当从 Web 浏览器触发 christopherkade.com/posts 时,将联系域 christopherkade.com 映射到的机器。

在其服务器中搜索路径 /posts。在您的情况下,我相信 /posts 的路由在服务器中不存在。结果 404 is displayed

解决这个问题的方法很少

要防止浏览器在触发请求时联系服务器christopherkade.com/posts,您可以在路由配置中保留mode : 'hash'

mode : 'hash' 的工作原理? 这是解决问题的一种方法

mode : 'hash' 使用默认的浏览器行为,即防止 http 请求触发 #

之后存在的详细信息

因此,当您触发 christopherkade.com/#/posts 时,浏览器会触发 christopherkade.com 并且一旦收到响应,就会调用 route config/posts 路由.

Lets assume that you have control over the server and you are adamant that you need # to be removed from the URL

那么你可以做的是配置服务器,使服务器每次发送任何路径时都响应相同的页面。一旦在浏览器中收到响应,路由将自动启动。

即使在您当前的程序中,当您单击页面中的任何链接(如工作、帖子)时,routeConfig 也会启动。这是因为此时未调用浏览器行为。

在你的情况下,你使用 github 来托管这个应用程序 mode: 'history' 我自己必须寻找一个特定的解决方案来解决这个问题。一旦我得到它,我会更新我的答案。

我希望这有用。

我推荐 nuxt,它使用 vue,但允许您使用以下方法为每个路由生成 html 页面:

$ nuxt generate

警告
路线需要在构建时可用。

Nuxt FAQ - How to deploy on GitHub Pages?

作为解决方法,我为每条路线创建了文件夹(使用脚本)并将 index.html 放入所有文件夹中。

404s 仍然无效。

作为解决方法,我复制了 index.html 并将其重命名为 404.html

这样,如果重新加载页面,您仍然可以获得正确的页面,但是这是通过 404.html file 提供的。

您可以通过简单的解决方法解决此问题。我结合了阅读有关此问题的多个问题的所有见解,最终这就是帮助我解决此问题的原因。

解决方案逻辑 - 您只需要在 dist 文件夹

中复制一份名为 404.htmlindex.html

修复步骤

转到你的 package.json 文件,在脚本下添加一个名为“部署”的新脚本,如下所示,你只需要在每次创建页面后执行它。uild。它会自动处理这个问题。

    "scripts": {
        "serve": "vue-cli-service serve",
        "build": "vue-cli-service build",
        "lint": "vue-cli-service lint",
        "deploy": "cd dist && cp index.html 404.html && cd .. && gh-pages -d dist"
    },

这将复制 index.html 并将其重命名为 404.html 并将 dist 文件夹推送到分支 gh-pages 下,之后您的脚本将出现在 vue ui 如下所示

如果您使用git subtree push --prefix dist origin gh-pages方式推送,那么将package.json中的deploy脚本编辑到下面

"deploy": "cd dist && cp index.html 404.html

然后执行下面的git命令。 PS,在手动使用 npm script 方法或从 vue ui

之前,不要忘记执行此脚本

git subtree push --prefix dist origin gh-pages

如果您使用 Nuxt,这可以解决问题。

layaouts/blank.vue

<template>
  <nuxt />
</template>

pages/redirect.vue

<template>
  <div></div>
</template>

<script>
export default {
  layout: 'blank',
  fetch({base, redirect, query}) {
    const param = query.p
    if (param === undefined) {
      return redirect('/')
    }
    const redirectPath = '/' + param.replace(base, '')
    return redirect(redirectPath)
  }
}
</script>

static/404.html

<html>
<head>
  <script>
    var pathName = window.location.pathname;
    var redirectPath = '/<repository-name>/redirect';
    location.href = redirectPath + '?p=' + encodeURI(pathName);
  </script>
</head>
</html>

https://gist.github.com/orimajp/2541a8cde9abf3a925dffd052ced9008