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

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

举个例子,是这样的:

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

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

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


当前回答

这是我为一个被AJAX请求的PHP应用程序所做的

$request_headers        = apache_request_headers();
$http_origin            = $request_headers['Origin'];
$allowed_http_origins   = array(
                            "http://myDumbDomain.example"   ,
                            "http://anotherDumbDomain.example"  ,
                            "http://localhost"  ,
                          );
if (in_array($http_origin, $allowed_http_origins)){  
    @header("Access-Control-Allow-Origin: " . $http_origin);
}

如果我的服务器允许请求源,返回$http_origin本身作为Access-Control-Allow-Origin头的值,而不是返回*通配符。

其他回答

对于ExpressJS应用程序,您可以使用:

app.use((req, res, next) => {
    const corsWhitelist = [
        'https://domain1.example',
        'https://domain2.example',
        'https://domain3.example'
    ];
    if (corsWhitelist.indexOf(req.headers.origin) !== -1) {
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    }

    next();
});

为了方便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动词。

我们也可以在全局中设置这个。asax文件用于Asp.net应用程序。

protected void Application_BeginRequest(object sender, EventArgs e)
    {

    // enable CORS
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "https://www.youtube.com");

    }

并非所有浏览器都使用HTTP_ORIGIN。HTTP_ORIGIN有多安全?对我来说,它在FF中是空的。 我有网站,我允许访问我的网站发送一个网站ID,然后我检查我的数据库记录与ID,并获得SITE_URL列值(www.yoursite.com)。

header('Access-Control-Allow-Origin: http://'.$row['SITE_URL']);

即使发送了一个有效的站点ID,请求也需要来自我的数据库中列出的与该站点ID相关的域。

我努力为一个运行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