当 Web 服务器上找不到文档时,它应该发送 404 状态码。这表示该文档不存在:搜索引擎不会对其进行索引,CDN 不会对其进行缓存,等等。如今,大多数 SPA 都会将所有内容都作为 200 提供服务,无论页面是否存在,但对于您来说,这种情况今天就停止了!
Remix 站点应发送 404 的主要情况有两种
第一种情况已由 Remix 处理,您无需自己抛出响应。它知道您的路由,因此它知道是否没有匹配项(考虑使用 通配符路由 来处理这种情况)。第二种情况由您决定,但它非常简单。
一旦您知道没有用户正在寻找的内容,您就应该抛出响应。
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
,而是接收一个包含您的响应 status
、statusText
和提取的 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>
);
}