是否有一种方法允许多个跨域使用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

其他回答

我有同样的问题与woff字体,多子域必须有访问。为了允许子域,我在我的httpd.conf中添加了这样的东西:

SetEnvIf Origin "^(.*\.example\.com)$" ORIGIN_SUB_DOMAIN=$1
<FilesMatch "\.woff$">
    Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN
</FilesMatch>

对于多个域,您可以更改SetEnvIf中的正则表达式。

如果你使用字体有困难,可以使用:

<FilesMatch "\.(ttf|ttc|otf|eot|woff)$">
    <IfModule mod_headers>
        Header set Access-Control-Allow-Origin "*"
    </IfModule>
</FilesMatch>

听起来,推荐的方法是让服务器从客户端读取Origin头,将其与您希望允许的域列表进行比较,如果匹配,则将Origin头的值作为响应中的Access-Control-Allow-Origin头回显给客户端。

使用.htaccess,你可以这样做:

# ----------------------------------------------------------------------
# Allow loading of external fonts
# ----------------------------------------------------------------------
<FilesMatch "\.(ttf|otf|eot|woff|woff2)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.example|dev02.otherdomain.example)$" AccessControlAllowOrigin=$0
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header merge Vary Origin
    </IfModule>
</FilesMatch>

如果您像我一样尝试了这么多代码示例以使它使用CORS工作,值得一提的是,您必须首先清除缓存,以尝试它是否实际工作,类似于旧图像仍然存在的问题,即使它在服务器上被删除了(因为它仍然保存在缓存中)。

例如,CTRL + SHIFT + DEL在谷歌Chrome删除你的缓存。

这帮助我在尝试了许多纯。htaccess解决方案后使用这段代码,这似乎是唯一一个工作(至少对我来说):

    Header add Access-Control-Allow-Origin "http://google.com"
    Header add Access-Control-Allow-Headers "authorization, origin, user-token, x-requested-with, content-type"
    Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

    <FilesMatch "\.(ttf|otf|eot|woff)$">
        <IfModule mod_headers.c>
            SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.com|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0
            Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        </IfModule>
    </FilesMatch>

还要注意,很多解决方案都说你必须输入Header set…但它是头添加....希望这能帮助到像我这样有同样问题的人。

Django中还有一个答案。要让一个视图允许来自多个域的CORS,以下是我的代码:

def my_view(request):
    if 'HTTP_ORIGIN' in request.META.keys() and request.META['HTTP_ORIGIN'] in ['http://allowed-unsecure-domain.com', 'https://allowed-secure-domain.com', ...]:
        response = my_view_response() # Create your desired response data: JsonResponse, HttpResponse...
        # Then add CORS headers for access from delivery
        response["Access-Control-Allow-Origin"] = request.META['HTTP_ORIGIN']
        response["Access-Control-Allow-Methods"] = "GET" # "GET, POST, PUT, DELETE, OPTIONS, HEAD"
        response["Access-Control-Max-Age"] = "1000"  
        response["Access-Control-Allow-Headers"] = "*"  
        return response