如何在 CORS 中指定多个域名?

通过动态设置 `Access-Control-Allow-Origin` 实现支持多个域名的 CORS 配置。

浏览器机制 中等 CORS 跨域 HTTP

在 HTTP 协议下的 CORS(跨源资源共享)机制中,浏览器限制了 Access-Control-Allow-Origin 头部只能接受单一值(一个特定域名或通配符 *);若要支持多个域名,不能简单通过逗号分隔或重复头部的方式来配置这些值,因为这违反了规范并会引发错误。解决方案的核心是在服务端根据请求中的 Origin 头值来动态设置响应头,具体步骤如下:

  1. 初始化允许域名清单:在服务端定义一个白名单列表,存放所有被允许的域名。

  2. 检查请求 Origin:当浏览器发送跨域请求时,会在标头中携带 Origin 值。您的后端代码需要:
    • 读取该值(例如,从 HTTP header 中获取)。
    • 检查其是否在允许的域名列表中。
  3. 动态设置 Access-Control-Allow-Origin
    • 如果检测到 Origin 与白名单匹配,则设置 Access-Control-Allow-Origin: [具体域名],其中 [具体域名] 直接引用请求中 Origin 的值以保证精确匹配。
    • 其他匹配选项例如 Access-Control-Allow-Credentials: true 用于支持 Cookie。
    • 对于无效或不属白名单的请求,设置默认/禁用策略处理如 HTTP 403 Forbidden

示例代码(使用 Node.js with Express):

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

// 允许的域名列表
const allowedOrigins = [
  "http://localhost:3000", 
  "https://example.com",
  "https://another-domain.com"
];

// CORS 中间件动态设置标头
app.use((req, res, next) => {
  const origin = req.headers.origin;
  // 检查是否在允许列表内
  if (allowedOrigins.indexOf(origin) > -1) {
    res.header('Access-Control-Allow-Origin', origin); //动态配置域名
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    res.header('Access-Control-Allow-Credentials', true); //若有cookie时
  } 
  next();
});

app.get('/api/resource', (req, res) => {
  //后端执行逻辑
});
app.listen(8000);

常见框架实现简例:

  • 如采用 Spring Framework,可用 .addAllowedOrigin 方法循环加域名,或类似工具。
  • Nginx 服务亦可反向代理设定逻辑来处理这一模式。 注意此种方案兼容使用凭证(Credentials)情景。