前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Next.js Route Handlers CORS 安全配置与风险规避
NeNext.js全栈边界

如何在 Route Handlers 中配置 CORS 策略以允许跨域请求?有哪些安全风险需要规避?

在 Next.js Route Handlers 中配置 CORS,本质是在响应中设置Access-Control-Allow-*头部。安全要点是:不用通配符*暴露敏感接口,须限制来源、方法和请求头,并妥善处理预检请求。

前端进阶之旅 · 一题精讲更新于 2026.09.05
Next.js#全栈边界#路由
先看核心答案读代码示例
理解线索

CORS 配置核心要点

  1. 设置响应头在 Handler 返回的 Response 中加 Access-Control-*
  2. 动态校验来源根据请求 Origin 判断是否允许
  3. 处理好预检非简单请求需响应 OPTIONS

敏感接口必须限制来源和方法,不能简单回显 Origin

核心回答

先记住这个答案

在 Route Handlers 中,可通过返回的Response对象显式添加 CORS 头部,如Access-Control-Allow-Origin。安全实践中,不要对所有接口统一使用*,而应基于Origin请求头动态校验,仅允许可信来源,并明确Access-Control-Allow-Methods与Access-Control-Allow-Headers。若涉及非简单请求,还需实现OPTIONS处理,返回适当的预检响应头。

  • CORS 头部需在响应中显式设置
  • 敏感接口勿用通配符 * 允许所有来源
  • 预检请求需单独处理 OPTIONS 方法

CORS 在 Route Handlers 中的工作原理

浏览器将跨域 HTTP 请求分为简单请求和预检请求。简单请求(如 GET、HEAD、POST 且 Content-Type 为 text/plain、multipart/form-data 或 application/x-www-form-urlencoded 等)直接发送,但响应需包含 Access-Control-Allow-Origin 等头部,否则浏览器拦截。其余情况会先发送 OPTIONS 预检,服务器必须正确响应 OPTIONS 并返回允许的方法、头部等,否则实际请求不会发出。

在 Route Handlers 中,每个 Handler 返回一个 Response,可自由设置 headers。因此配置 CORS 就是创建响应时添加对应头部。Next.js 不会自动添加 CORS 头,除非使用中间件或反向代理。若不定义 OPTIONS,Next.js 默认会生成一个基于已定义方法的简单 OPTIONS 响应,但通常需要自定义以包含预检所需头部。

允许特定前端的 JSON POST 接口

场景:前端订单查询接口 app/api/order/route.ts,仅允许 https://shop.example.com 调用。实现时,读取 request.headers.get('origin'),如果等于允许来源,则在响应头设置 Access-Control-Allow-Origin 为该来源,并加上 Vary: Origin;否则不设置。针对 POST 预检,定义 OPTIONS 方法,返回 204,并设置 Access-Control-Allow-Methods: POST 及允许的请求头。

若需要携带凭证(如 Authorization 头),不能使用 * 通配符,必须明确回显具体 Origin,并设置 Access-Control-Allow-Credentials: true。此外,需验证 OPTIONS 请求的 Access-Control-Request-Method 是否与允许列表匹配,若不匹配则返回 403。此做法将风险控制在可信来源内。

带来源白名单的 CORS 配置示例TypeScript
const ALLOWED_ORIGINS = ['https://shop.example.com'];

export async function OPTIONS(request: Request) {
  const origin = request.headers.get('origin');
  if (!origin || !ALLOWED_ORIGINS.includes(origin)) {
    return new Response(null, { status: 403 });
  }
  const requestedMethod = request.headers.get('access-control-request-method');
  if (requestedMethod !== 'POST') {
    return new Response(null, { status: 403 });
  }
  return new Response(null, {
    status: 204,
    headers: {
      'Access-Control-Allow-Origin': origin,
      'Vary': 'Origin',
      'Access-Control-Allow-Methods': 'POST',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    },
  });
}

export async function POST(request: Request) {
  const origin = request.headers.get('origin');
  if (!origin || !ALLOWED_ORIGINS.includes(origin)) {
    return Response.json({ error: 'Forbidden' }, { status: 403 });
  }
  // 处理业务逻辑
  return Response.json({ ok: true }, {
    headers: {
      'Access-Control-Allow-Origin': origin,
      'Vary': 'Origin',
    },
  });
}

演示了动态校验 Origin 并回显,避免通配符。Vary: Origin 告知缓存依据 Origin 区分。

CORS 配置的失败边界与适用条件

使用 * 通配符时,无法携带 Cookie,若接口依赖 Cookie 鉴权将失效。但如果仅用于公开只读数据,可接受。另一个陷阱是:当校验失败时,简单请求会收到响应但被浏览器拦截,实际请求已经到达服务器;若服务器误将 Origin 反射(如直接取请求头)就会允许任何来源,造成风险。

处理预检时若省略 Access-Control-Allow-Headers,浏览器会拒绝带自定义头的请求。同时,设置 Access-Control-Max-Age 可缓存预检结果减少往返,但更新策略时需注意缓存。若要全局配置,可考虑 Middleware 或 next.config.js 的 headers,但 Route Handler 内配置更适合有特定安全要求的接口。

回答前,多想一步

容易答错的地方

错误假设 Next.js 自动提供 CORS
多人误以为 Next.js Route Handlers 默认允许跨域,实则必须手动设置响应头。若不设置,浏览器会阻止跨域响应,服务端可能仍处理了请求。安全上必须显式配置。
反射任意 Origin 为最大风险
直接设置 Access-Control-Allow-Origin: request.headers.get('origin') 会让恶意网站也能调用接口,导致 CSRF 或其他攻击。必须校验来源是否在可信列表中。
试着用自己的话回答

面试官还会怎么问?

如果允许的来源不固定,如何动态配置?

应根据请求的 Origin 查询数据库或配置列表,判断是否允许,并动态返回。而非简单反射。同样需加入 Vary 头以利于缓存。

如何处理带 Cookie 的跨域请求?

必须设置 Access-Control-Allow-Credentials: true,且 Access-Control-Allow-Origin 不能为 *,必须明确指定具体来源。另外客户端需设置 credentials: 'include'。

OPTIONS 方法必须单独实现吗?

如果只处理简单请求,可不实现。但若使用 Authorization 头或非简单 Content-Type,就必须实现 OPTIONS 并返回正确的 Access-Control-* 响应头。

从一道题,走向一组知识

把知识连起来

全栈边界

如何在 Route Handlers 中实现基于 API Key 的请求验证?请说明密钥来源与比对策略。

同属「全栈边界」专题,接着看 Next.js Route Handlers API Key 验证与密钥比对策略 在具体场景中的处理方式。

全栈边界

Route Handlers 如何用于实现基于 JWT 的认证中间件?请说明请求拦截与上下文传递方式。

同属「全栈边界」专题,接着看 Next.js Route Handlers JWT 认证中间件 请求拦截 上下文传递 在具体场景中的处理方式。

参考资料

  • route.js

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. CORS 在 Route Handlers 中的工作原理
  3. 允许特定前端的 JSON POST 接口
  4. CORS 配置的失败边界与适用条件
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑