You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用React和Express处理动态404页面及404状态码(含SSR场景)

React中处理404页面与正确状态码的方案

1. 客户端渲染(SPA)场景:修复404页面状态码为200的问题

纯客户端渲染的React应用里,浏览器的HTTP状态码由首次请求的服务器响应决定。如果用户直接访问未定义的路由,服务器通常会返回index.html(状态码200),之后客户端路由才渲染NotFound页面,导致状态码显示异常。解决这个问题需要服务器端配合:

服务器端路由校验配置

配置你的服务器(Nginx、Express等),只对React应用中定义的有效路由返回index.html;未匹配的路由直接返回404状态码和自定义NotFound页面。

Express示例:

const path = require('path');
const express = require('express');
const app = express();

// 定义所有有效客户端路由
const validRoutes = ['/', '/about', '/products'];

app.use(express.static(path.join(__dirname, 'build')));

app.get('*', (req, res) => {
  if (validRoutes.includes(req.path)) {
    res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
  } else {
    // 返回404状态码和NotFound页面
    res.status(404).sendFile(path.resolve(__dirname, 'build', '404.html'));
  }
});

app.listen(3000);

客户端补充处理:
如果用户是从有效路由内部跳转到无效路由(客户端导航),浏览器不会发送新的HTTP请求,状态码仍为200。这种情况下,可以通过修改页面标题、添加明确的404提示,或加入meta标签帮助搜索引擎识别:

import { useEffect } from 'react';

function NotFound() {
  useEffect(() => {
    document.title = '404 - 页面不存在';
  }, []);

  return (
    <div>
      <meta name="robots" content="noindex, nofollow" />
      <h1>404 - 页面不存在</h1>
    </div>
  );
}

2. SSR/预渲染场景:让404页面返回真实404状态码

无论是使用Next.js、Gatsby这类框架,还是自定义SSR服务,核心是在渲染阶段判断路由有效性,无效则设置响应状态码为404。

Next.js示例(支持SSR/SSG)

  • SSR场景(getServerSideProps):
    创建pages/[...notFound].js捕获所有未匹配路由:
export async function getServerSideProps(context) {
  // 自定义逻辑:校验当前路由是否有效
  const isValidRoute = checkValidRoute(context.resolvedUrl);
  
  if (!isValidRoute) {
    // 设置响应状态码为404
    context.res.statusCode = 404;
  }

  return { props: {} };
}

export default function NotFound() {
  return <h1>404 - 页面不存在</h1>;
}
  • 静态预渲染(SSG)场景:
    通过getStaticPaths声明所有有效路由,未包含的路由会自动触发404:
export async function getStaticPaths() {
  // 获取所有有效路由(比如从CMS或数据库拉取)
  const validPaths = await fetchAllValidRoutes();
  
  return {
    paths: validPaths.map(path => ({ params: { slug: path } })),
    fallback: 'blocking' // 未定义的路由会返回404
  };
}

export async function getStaticProps(context) {
  const isValid = checkValidRoute(context.params.slug);
  if (!isValid) {
    return { notFound: true }; // Next.js自动返回404状态码
  }
  return { props: {} };
}

自定义SSR服务示例

在渲染React组件前,先判断路由有效性,再设置响应状态码:

import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter } from 'react-router-dom/server';
import App from './App';
import express from 'express';

const app = express();

function checkValidRoute(path) {
  // 自定义逻辑:校验路由是否存在
  const validRoutes = ['/', '/about'];
  return validRoutes.includes(path);
}

app.get('*', (req, res) => {
  const statusCode = checkValidRoute(req.path) ? 200 : 404;

  const appHtml = renderToString(
    <StaticRouter location={req.path}>
      <App />
    </StaticRouter>
  );

  const html = `
    <!DOCTYPE html>
    <html>
      <head><title>${statusCode === 404 ? '404页面' : '首页'}</title></head>
      <body>${appHtml}</body>
    </html>
  `;

  res.status(statusCode).send(html);
});

app.listen(3000);

3. 在NotFound页面发送真实的404状态码

SSR/预渲染场景

直接在服务器端设置响应状态码为404即可,这是浏览器和搜索引擎能识别的真实HTTP状态码,无需额外客户端处理。

SPA场景(客户端内部跳转)

纯客户端场景下,浏览器的状态码由首次请求决定,无法直接修改。但可以通过以下方式补充:

  • 向服务器发送404标记请求:在NotFound组件挂载时,发送HEAD请求到服务器端点,让服务器记录404访问:
import { useEffect } from 'react';

function NotFound() {
  useEffect(() => {
    // 发送HEAD请求,服务器返回404状态码
    fetch('/api/mark-404', { method: 'HEAD' });
  }, []);

  return <h1>404 - 页面不存在</h1>;
}

服务器端对应端点:

app.head('/api/mark-404', (req, res) => {
  res.status(404).end();
});
  • 添加搜索引擎识别标签:在NotFound页面加入meta标签,告知搜索引擎这是404页面:
<meta name="robots" content="noindex, nofollow" />

内容的提问来源于stack exchange,提问作者Bardhavar Ravindhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:43:24