如何处理 Nuxt SSR 错误并显示自定义 404 || 500页?

Mil*_*avc 5 server-side-rendering nuxt.js vue-ssr nuxtserverinit

当 Nuxt 的 SSR 遇到错误时,你如何处理错误?

目前我正在使用error()处理程序,但它在生产中不起作用?这是我的 Nuxt 应用程序的示例。

异步数据

 async asyncData({ store, route, error }) {
    return store.dispatch( NAMESPACES.USERS + ACTIONS.GET_DETAIL, userId ).then(response => ({
      data: response,
    })).catch((e) => {
      error(e)
    })
  } 
Run Code Online (Sandbox Code Playgroud)

错误.vue

  <vis-container>
    <vis-row class="error">
      <vis-col md="8" class="error__component">
        <component :is="errorPage" :error="error.statusCode" />
      </vis-col>

      <vis-col md="8" class="error__contact">
        <p class="error__contact__title">{{ $t('error_page.question') }}</p>
      </vis-col>
    </vis-row>
  </vis-container>
</template>

<script>
export default {
  props: ['error'],
components: {
    NotFound: () => import('@/components/error/NotFound'),
    InternalServerError: () => import('@/components/error/InternalServerError'),
  },
    computed: {
    errorPage() {
      if (this.error.statusCode === 500) {
        return 'InternalServerError'
      }

      return 'NotFound'
    },
  },
}
</script>

Run Code Online (Sandbox Code Playgroud)

mav*_*riq 1

此答案仅与 SSR 模式相关。

可能存在不同类型的错误。我将在这里提供有关其中两种类型的信息:

  • 动态路由错误
  • 数据获取期间出错(nuxt >= 2.12,fetchhook)

动态路由的错误处理[选项 1]:

根据 Nuxt关于生命周期的文档,有一个特殊的validate钩子。它的主要目的是验证动态路由参数。
在这里您可以找到更详细的描述,但通常您需要提供在参数有效和无效时validate返回的实现。 如果是nuxt,将返回 404 响应和默认错误页面(您还可以在验证函数执行期间抛出预期或意外错误以及自定义默认错误页面)。 这里重要说明:truefalse
false

该方法将上下文对象作为参数。

动态路由的错误处理[选项 2]:

每当你需要在 Nuxt 中为服务器端渲染的页面返回不同的状态代码时,你就需要使用中间件。

这是主要思想 - 您必须定义自己的中间件来验证此处的 url(可能内部有异步逻辑)。

import { Context } from "@nuxt/types";
import { isUrlValid } from "~/services/validateRoute";

export default async function (context: Context) {
  if (!(await isUrlValid(context.route.path))) {
    context.error({
      statusCode: 404,
      message: `Invalid route: ${context.route.path}`,
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

为了使其工作,应该链接到相应的动态路由页面:

import Vue from "vue";
import Component from "vue-class-component";
@Component({
  middleware: "validateRoute",
})
export default class RedirectPage extends Vue {}
Run Code Online (Sandbox Code Playgroud)

工作应用程序示例在这里:https://github.com/DamirsCorner/20210521-nuxt-dynamic-route-404

资料来源:https ://www.damirscorner.com/blog/posts/20210521-404PageForNuxtDynamicNestedRoutes.html

数据获取错误处理:

Nuxt 文档说:

如果获取数据时出现错误,则不会加载正常的 Nuxt 错误页面 - 并且您不应在 fetch() 中使用 Nuxt 重定向或错误方法。相反,您需要使用 $fetchState.error 在组件内处理它。

所以,这非常简单:

<template>
  <div>
    <p v-if="$fetchState.pending">Loading....</p>
    <p v-else-if="$fetchState.error">Error while fetching mountains</p>
    <ul v-else>
      <li v-for="(mountain, index) in mountains" :key="index">
        {{ mountain.title }}
      </li>
    </ul>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        mountains: []
      }
    },
    async fetch() {
      this.mountains = await fetch(
        'https://api.nuxtjs.dev/mountains'
      ).then(res => res.json())
    }
  }
</script>
Run Code Online (Sandbox Code Playgroud)

从这个示例中您可以看到,您将无法更改响应代码,因为该阶段的错误将被解释为响应代码为 200 的正常情况。