コンテンツにスキップ

Not Found Handling

このコンテンツはまだ日本語訳がありません。

未找到(404)处理

当 Web 服务器上找不到文档时,它应该发送 404 状态代码。这向机器表明文档不存在:搜索引擎不会索引它,CDN 不会缓存它,等等。如今,大多数 SPA 只是将所有内容都作为 200 来提供,无论页面是否存在,但对于您来说,这种情况今天就结束了!

Remix 网站应该发送 404 的情况主要有两种:

  • URL 与应用中的任何路由均不匹配
  • 您的加载器未找到任何数据

第一种情况已由 Remix 处理,您无需自己抛出响应。它知道您的路由,因此它知道是否没有匹配项(考虑使用 Splat Route 来处理这种情况)。第二种情况由您决定,但这真的很容易。

如何发送 404

一旦您知道自己没有用户正在寻找的内容,您就应该_做出回应_。

// app/routes/page.$slug.tsx
export async function loader({
params,
}: LoaderFunctionArgs) {
const page = await db.page.findOne({
where: { slug: params.slug },
});
if (!page) {
throw new Response(null, {
status: 404,
statusText: "Not Found",
});
}
return json(page);
}

Remix 将捕获响应并将您的应用发送到 错误边界 路径。它实际上与 Remix 的自动 [错误处理][错误] 完全一样,但您不会从 useRouteError() 接收 Error,而是会收到一个包含响应 statusstatusText 和提取的 data 的对象。

抛出响应的好处是,加载器中的代码会停止执行。其余代码无需处理页面是否定义的可能性(这对于 TypeScript 来说尤其方便)。

抛出还可确保如果加载器未成功,您的路由组件不会呈现。您的路由组件只需考虑快乐路径。它们不需要待处理状态、错误状态,或者我们这里例子中的未找到状态。

根错误边界

您的应用根目录下可能已经有一个。这将处理嵌套路由中未处理的所有抛出的响应。以下是示例:

export function ErrorBoundary() {
const error = useRouteError();
return (
<html>
<head>
<title>Oops!</title>
<Meta />
<Links />
</head>
<body>
<h1>
{isRouteErrorResponse(error)
? `${error.status} ${error.statusText}`
: error instanceof Error
? error.message
: "Unknown Error"}
</h1>
<Scripts />
</body>
</html>
);
}