在Next.js中传递动态路由的无效参数时,如何返回404 Not Found页面和HTTP状态?

niwlg2el  于 2022-11-29  发布在  其他
关注(0)|答案(2)|浏览(214)

例如,我有一个动态路由/blog/[article-id]
当访问现有的博客文章/blog/id-that-exist时,它按预期工作,现在我想正确处理/blog/id-that-does-not-exist的情况。
/blog/[id].jsx中的代码如下所示:

export const getStaticPaths async () => {
  return {
    fallback: true,
    paths: (await sequelize.models.Article.findAll()).map(
      article => {
        return {
          params: {
            pid: article.slug,
          }
        }
      }
    ),
  }
}

export const getStaticProps async () => {
  // Try to get it from the database. Returns none if does not exist.
  const article = await sequelize.models.Article.findOne({
    where: { slug: pid },
  });
  return { props: { article: article } };
}

const ArticlePage = (props) => {
  // This can happen due to fallback: true while waiting for
  // a page that was not rendered at build time to build.
  const router = useRouter()
  if (router.isFallback) {
    return <div>loading</div>;
  }
  return (
    <div>{props.article.body}</div>
  );
};

export const getStaticPaths = getStaticPathsArticle;
export const getStaticProps = getStaticPropsArticle;
export default ArticlePage;

我看到了这个相关的问题:How to handle not found 404 for dynamic routes in Next.js which is calling API?,但我不确定它是否与我在这里要求的相同,因为它不依赖于使用的任何外部API。

ru9i0ody

ru9i0ody1#

来自Next.js 10的notFound: true

从Next.js 10开始,我们可以:

export const getStaticProps async () => {
  // Try to get it from the database. Returns none if does not exist.
  const article = await sequelize.models.Article.findOne({
    where: { slug: pid },
  });
  if (!article) {
    return {
      notFound: true
    }
  }
  return { props: { article: article } };
}

记录在:https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation
当返回notFound时,呈现函数ArticlePage永远不会被调用,而是返回默认的404页。
但是请注意,ArticlePage确实获得了
开发模式中的某些原因:

  • 我没有得到预期的404 HTTP状态代码
  • ArticlePage,因此如果您忘记处理回退情况,它可能会由于缺少属性而崩溃

这让我有点困惑。但在生产模式下,一切都按预期运行。

Next.js 10之前的解决方法

如www.example.com所示https://github.com/vercel/next.js/discussions/10960#discussioncomment-1201,您之前可以执行以下操作:

const ArticlePage = (props) => {
  if (!props.article) {
    return <>
      <Head>
        <meta name="robots" content="noindex">
      </Head>
      <DefaultErrorPage statusCode={404} />
    </>
  }
  return (
    <div>{props.article.body}</div>
  );
};

但这并不理想,因为我认为它没有正确设置HTTP返回代码,而且我不知道如何设置。
在Next.js 10.2.2上进行了测试。

zzlelutf

zzlelutf2#

我已经阅读了您关于Next.jsv.10之后的解决方案的回答,但是我不知道在开发期间显示预期的http 404代码有什么问题。
我使用Next.JS v.12,在开发过程中通常会得到预期的404

import { GetStaticPaths, GetStaticProps } from 'next'
import { useRouter } from 'next/router'
import { ParsedUrlQuery } from 'querystring'
import Loading from '../../components/loading'

export const getStaticPaths: GetStaticPaths = async () => {
   //your paths

    return { paths, fallback: true }
}

export const getStaticProps: GetStaticProps = async ({ params }: { params?: ParsedUrlQuery }) => {
   //get your props
if (!target){
return {notFound: true}
}

    return { props: { ... }, revalidate: 86400}
}

function Index({ ... }) {
    const router = useRouter()
    
    if (router.isFallback) {
        return <Loading />
    }
    return (
        <div>
           //my content
        </div>
    )
}

export default Index

如果找不到目标,它会在pages/404.tsx中呈现我的自定义404组件(如果我创建了一个或仅默认的404页面)。
这在开发和生产期间应该正常工作。

相关问题