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

NestJS CORS问题排查:Access-Control-Allow-Origin多值异常

排查NestJS中CORS响应头重复问题

我用NestJS开发后端,前端采用React框架。在main.ts里配置了如下CORS规则:

const whitelist = [
  process.env.APP_WEBSITE_URL as string,
  process.env.APP_URL as string,
  process.env.SUPER_TOKEN_CONNECTION_STRING as string,
  'http://localhost:3000/' as string,
];
app.enableCors({
  origin: whitelist,
  allowedHeaders: ['content-type', ...supertokens.getAllCORSHeaders()],
  credentials: true,
  methods: ['GET', 'PUT', 'POST', 'OPTIONS', 'PATCH'],
});

当前前端部署在app.jetabe.com,后端部署在api.jetabe.com,请求时遇到CORS错误:

Access to fetch at 'https://api.jetabe.com/applicationType' from origin 'https://app.jetabe.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains multiple values 'https://app.jetabe.com, *', but only one is allowed. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

以下是排查Access-Control-Allow-Origin头出现*来源的具体步骤:

  • 检查反向代理/服务器配置
    如果后端通过Nginx、Apache等反向代理部署,优先排查代理配置文件,确认是否存在add_header Access-Control-Allow-Origin *;这类规则。代理层添加的CORS头会和NestJS返回的头重复,导致多值冲突。

  • 验证NestJS全局中间件与拦截器
    排查项目中是否有自定义全局拦截器、中间件,或者第三方模块(除Supertokens外)自动注入了CORS配置。比如有没有手动在响应中添加Access-Control-Allow-Origin头的代码,或者重复注册了cors中间件。

  • 核对环境变量与白名单配置
    确认APP_WEBSITE_URL、APP_URL等环境变量的值是否为https://app.jetabe.com,注意浏览器发送的origin不带结尾斜杠,白名单里的http://localhost:3000/带斜杠可能导致匹配失败。同时检查环境变量是否正确加载,避免白名单中出现undefined,触发NestJS的CORS逻辑异常。

  • 排查Supertokens配置冲突
    检查Supertokens的初始化代码,确认是否开启了它自身的CORS配置。如果Supertokens也设置了CORS头,会和NestJS的配置重复,需要禁用其中一方的CORS设置,仅保留NestJS的配置即可。

  • 调试CORS匹配逻辑
    临时修改CORS的origin为自定义函数,打印请求origin和白名单匹配情况,定位问题:

    app.enableCors({
      origin: (origin, callback) => {
        console.log('当前请求origin:', origin);
        console.log('CORS白名单:', whitelist);
        // 统一格式,去掉URL结尾斜杠
        const normalizedWhitelist = whitelist.map(url => url.replace(/\/$/, ''));
        const normalizedOrigin = origin?.replace(/\/$/, '');
        if (normalizedWhitelist.includes(normalizedOrigin) || !origin) {
          callback(null, origin);
        } else {
          callback(new Error('Not allowed by CORS'));
        }
      },
      allowedHeaders: ['content-type', ...supertokens.getAllCORSHeaders()],
      credentials: true,
      methods: ['GET', 'PUT', 'POST', 'OPTIONS', 'PATCH'],
    });
    

    查看后端日志,确认请求origin是否被正确匹配,以及返回的Access-Control-Allow-Origin头是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:55:29