多域名调用Vercel部署的Next.js API时缓存导致CORS头错误如何解决
解决方案
核心原因是Vercel的边缘缓存会将完整响应(包括CORS头)统一存储,不同来源的请求命中同一份缓存时就会返回错误的Access-Control-Allow-Origin值,304协商缓存场景下这个问题会被放大。你可以通过以下方案解决,无需为每个域名单独配置代理:
1. 配置Vary: Origin响应头(推荐,兼容缓存需求)
HTTP协议的Vary头用于告知缓存服务器,指定的请求头会影响响应内容,不同取值的请求需要单独缓存。只要将Origin加入Vary列表,Vercel就会为不同来源的请求分别缓存响应,不会出现CORS头串用的问题。
有两种常用配置方式:
Next.js代码内配置
如果你用Pages Router的API路由,在接口返回前添加头信息:
如果你用App Router的路由处理器,写法如下:export default function handler(req, res) { // 先校验请求Origin是否在你的允许域名列表中 const allowedOrigins = ['https://domain-a.com', 'https://domain-b.com'] const requestOrigin = req.headers.origin if (allowedOrigins.includes(requestOrigin)) { res.setHeader('Access-Control-Allow-Origin', requestOrigin) } // 关键配置:告诉缓存按Origin区分存储 res.setHeader('Vary', 'Origin') // 其他业务逻辑 res.status(200).json(yourData) }export async function GET(request) { const allowedOrigins = ['https://domain-a.com', 'https://domain-b.com'] const requestOrigin = request.headers.get('origin') const response = NextResponse.json(yourData) if (allowedOrigins.includes(requestOrigin)) { response.headers.set('Access-Control-Allow-Origin', requestOrigin) } response.headers.set('Vary', 'Origin') return response }vercel.json全局配置
如果需要给所有API接口统一生效,可以在项目根目录的vercel.json中添加配置:{ "headers": [ { "source": "/api/(.*)", "headers": [ { "key": "Vary", "value": "Origin" } ] } ] }
2. 禁用API响应缓存(适合不需要缓存的接口)
如果你的API接口本身不需要走缓存,可以直接添加Cache-Control: no-store头,Vercel就不会存储响应,每次请求都会执行你的接口逻辑生成正确的CORS头,从根源避免缓存串用问题:
// 以Pages Router为例 res.setHeader('Cache-Control', 'no-store')
注意事项
- 不要直接返回
Access-Control-Allow-Origin: *,如果接口需要支持携带凭证(Cookie等),通配符会直接触发CORS错误,一定要动态匹配请求的Origin值 - 如果你的响应还会根据其他请求头变化(比如
Accept-Encoding),可以将这些头也一并加入Vary列表,用逗号分隔即可
内容的提问来源于stack exchange,提问作者Luze26
相关产品推荐
相关产品推荐

