← 返回题目列表

SSR 中重定向和 HTTP 状态码应该如何设计?

中等 第 21 / 25 题 更新于 2026/07/29
SSR重定向HTTP 状态码SEO

简化版

SSR 中重定向不能只靠客户端 location.href,因为首屏请求本身就是一次 HTTP 响应。更规范的做法是在服务端根据场景返回合适状态码:临时跳转用 302 或 307,永久迁移用 301 或 308;页面不存在返回 404;服务端异常返回 500;无权限可以返回 401、403 或跳登录页。状态码会影响浏览器行为、搜索引擎收录和 CDN 缓存。

详细版

SSR 页面既是前端页面,也是服务端 HTTP 响应。状态码设计不清楚,会导致 SEO 错误、缓存错误、监控误报和用户体验问题。

例如商品下架后如果仍返回 200,只在页面里写“商品不存在”,搜索引擎和监控都会认为页面正常。登录态失效如果只在客户端跳转,用户会先看到错误页面再跳走,还会造成首屏闪烁。

面试里要把重定向分成业务跳转、权限跳转、资源迁移和异常降级,不同场景选择不同状态码。

完整版教学

一、SSR 为什么要关注状态码

CSR 应用常常返回一个固定的 index.html

SSR 则可以针对每个 URL 返回不同 HTML 和状态码。

这让 SSR 更适合 SEO,但也要求前端理解 HTTP 语义。

状态码不是后端独有问题,SSR 页面负责人也要参与设计。

二、常见状态码选择

场景建议状态码说明
页面永久换地址301 / 308有 SEO 迁移含义
登录后临时跳转302 / 307不代表资源永久迁移
内容不存在404搜索引擎应知道不存在
无权限访问401 / 403 / 302取决于产品策略
服务端异常500便于监控识别
服务降级可展示200 + 降级内容页面仍可正常服务

三、301、302、307、308 的区别

301 和 308 表示永久重定向。

302 和 307 表示临时重定向。

301、302 在历史实现里可能改变请求方法。

307、308 更强调保持原请求方法和请求体。

页面 GET 请求里常用 301、302 已经足够,但接口和表单跳转要更谨慎。

四、代码示例

export async function handleProductPage(params) {
  const product = await getProduct(params.id);

  if (!product) {
    return renderNotFound({ status: 404 });
  }

  if (product.canonicalPath !== params.path) {
    return redirect(product.canonicalPath, 301);
  }

  return renderProduct(product, { status: 200 });
}

这里的重点是状态码跟业务语义一致,而不是全部返回 200。

五、SEO 相关影响

永久迁移适合用 301 或 308,把权重传递到新 URL。

临时活动页跳转不要误用 301,否则搜索引擎可能长期记住旧规则。

不存在的内容要返回 404 或 410,而不是软 404。

规范 URL 可以配合 canonical 标签,但它不能替代正确的 HTTP 状态码。

SEO 场景里,HTML 文案和 HTTP 状态码都重要;只改页面内容是不完整的。

六、权限跳转的取舍

登录页跳转常用 302。

API 未登录常用 401。

已登录但无权限常用 403。

对于需要 SEO 的公开页,未登录也可以返回 200,只隐藏个性化区域。

对于私有页面,服务端直接重定向可以减少首屏闪烁。

七、误区和追问

  • 误区:SSR 页面统一返回 200 最简单。 简单但会破坏 SEO、监控和缓存判断。
  • 误区:客户端跳转可以替代服务端重定向。 客户端跳转发生得更晚,搜索引擎和首屏体验都受影响。
  • 误区:所有跳转都用 301。 301 有永久含义,活动页和登录跳转不适合乱用。
  • 追问:商品下架返回 404 还是 200? 如果资源不可访问且没有替代内容,倾向 404;如果是可解释的下架页,可结合业务和 SEO 策略决定。
  • 追问:无权限返回 403 还是跳登录? 未登录可 302 到登录页,已登录无权限更适合 403 或权限说明页。
  • 追问:状态码会影响 CDN 吗? 会,不同状态码可能被不同策略缓存,错误缓存会放大事故。

八、面试收束

回答可以落在“HTTP 语义、用户体验、SEO、缓存、监控”五个维度。

这样能体现你不是只会写页面,也理解 SSR 的服务端响应责任。