是否有一种方法允许多个跨域使用Access-Control-Allow-Origin头?

我知道*,但它太开放了。我只讲几个域。

举个例子,是这样的:

Access-Control-Allow-Origin: http://domain1.example, http://domain2.example

我已经尝试了上面的代码,但它似乎不能在Firefox中工作。

是否可以指定多个域,还是只能指定一个域?


当前回答

我努力为一个运行HTTPS的域设置这个,所以我想我会分享这个解决方案。我在我的httpd.conf文件中使用了以下指令:

    <FilesMatch "\.(ttf|otf|eot|woff)$">
            SetEnvIf Origin "^http(s)?://(.+\.)?example\.com$" AccessControlAllowOrigin=$0
            Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    </FilesMatch>

将example.com更改为您的域名。在httpd.conf文件中的<VirtualHost x.x.x.x:xx>中添加此内容。注意,如果你的VirtualHost有一个端口后缀(例如:80),那么这个指令将不适用于HTTPS,所以你还需要去/etc/apache2/sites-available/default-ssl并在那个文件中添加相同的指令,在<VirtualHost _default_:443>部分。

配置文件更新后,需要在终端上执行以下命令:

a2enmod headers
sudo service apache2 reload

其他回答

下面是如何回显Origin头,如果它匹配你的域与Nginx,这是有用的,如果你想为一个字体多子域:

location /fonts {
    # this will echo back the origin header
    if ($http_origin ~ "example.org$") {
        add_header "Access-Control-Allow-Origin" $http_origin;
    }
}

对于多个域,在你的。htaccess:

<IfModule mod_headers.c>
    SetEnvIf Origin "http(s)?://(www\.)?(domain1.example|domain2.example)$" AccessControlAllowOrigin=$0$1
    Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    Header set Access-Control-Allow-Credentials true
</IfModule>

PHP代码:

$httpOrigin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : null;
if (in_array($httpOrigin, [
    'http://localhost:9000', // Co-worker dev-server
    'http://127.0.0.1:9001', // My dev-server
])) header("Access-Control-Allow-Origin: ${httpOrigin}");
header('Access-Control-Allow-Credentials: true');

如上所述,Access-Control-Allow-Origin应该是唯一的,如果您位于CDN(内容分发网络)后面,则应该将Vary设置为Origin。

Nginx配置的相关部分:

if ($http_origin ~* (https?://.*\.mydomain\.com(:[0-9]+)?)) {
  set $cors "true";
}
if ($http_origin ~* (https?://.*\.my-other-domain\.com(:[0-9]+)?)) {
  set $cors "true";
}

if ($cors = "true") {
  add_header 'Access-Control-Allow-Origin' "$http_origin";
  add_header 'X-Frame-Options' "ALLOW FROM $http_origin";
  add_header 'Access-Control-Allow-Credentials' 'true';
  add_header 'Vary' 'Origin';
}

为了方便ASMX服务的多域访问,我在全局中创建了这个函数。asax文件:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    string CORSServices = "/account.asmx|/account2.asmx";
    if (CORSServices.IndexOf(HttpContext.Current.Request.Url.AbsolutePath) > -1)
    {
        string allowedDomains = "http://xxx.yyy.example|http://aaa.bbb.example";

        if(allowedDomains.IndexOf(HttpContext.Current.Request.Headers["Origin"]) > -1)
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", HttpContext.Current.Request.Headers["Origin"]);

        if(HttpContext.Current.Request.HttpMethod == "OPTIONS")
            HttpContext.Current.Response.End();
    }
}

这也允许CORS处理OPTIONS动词。