Access-Control-Allow-Origin Домены нескольких источников? - PullRequest
946 голосов
/ 31 октября 2009

Можно ли разрешить использование нескольких междоменных доменов с использованием заголовка Access-Control-Allow-Origin?

Я знаю о *, но он слишком открыт. Я действительно хочу разрешить только пару доменов.

Например, что-то вроде этого:

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

Я пробовал приведенный выше код, но, похоже, он не работает в Firefox.

Можно ли указать несколько доменов или я застрял только на одном?

Ответы [ 28 ]

796 голосов
/ 05 декабря 2009

Похоже, рекомендованный способ сделать так, чтобы ваш сервер считывал заголовок 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>
199 голосов
/ 17 сентября 2011

Другое решение, которое я использую в PHP:

$http_origin = $_SERVER['HTTP_ORIGIN'];

if ($http_origin == "http://www.domain1.com" || $http_origin == "http://www.domain2.com" || $http_origin == "http://www.domain3.com")
{  
    header("Access-Control-Allow-Origin: $http_origin");
}
103 голосов
/ 18 июня 2012

Это сработало для меня:

SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.example|domain2\.example)$" origin_is=$0 
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is

Когда введено .htaccess, оно будет работать точно.

86 голосов
/ 18 мая 2011

У меня была такая же проблема с 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.

60 голосов
/ 14 сентября 2012

Вот как вернуть заголовок Origin, если он соответствует вашему домену с Nginx, это полезно, если вы хотите обслуживать шрифт несколькими поддоменами:

location /fonts {
    # this will echo back the origin header
    if ($http_origin ~ "example.org$") {
        add_header "Access-Control-Allow-Origin" $http_origin;
    }
}
24 голосов
/ 26 декабря 2012

Вот что я сделал для приложения PHP, которое запрашивает AJAX

$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.

19 голосов
/ 20 февраля 2010

Есть один недостаток, о котором вы должны знать: как только вы отправляете исходные файлы на CDN (или любой другой сервер, на котором не разрешены сценарии) или если ваши файлы кэшируются на прокси, изменение ответа основывается на Заголовок запроса 'Origin' не будет работать.

18 голосов
/ 11 марта 2014

Для нескольких доменов, в вашем .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>
14 голосов
/ 10 января 2015

Для пользователей Nginx разрешить CORS для нескольких доменов. Мне нравится пример @ marshall, хотя его ответы соответствуют только одному домену. Чтобы сопоставить список доменов и поддоменов, это регулярное выражение облегчает работу со шрифтами:

location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {
   if ( $http_origin ~* (https?://(.+\.)?(domain1|domain2|domain3)\.(?:me|co|com)$) ) {
      add_header "Access-Control-Allow-Origin" "$http_origin";
   }
}

Это будет отображать только заголовки «Access-Control-Allow-Origin», которые соответствуют данному списку доменов.

14 голосов
/ 27 июня 2015

Для IIS 7.5+ с установленным модулем URL Rewrite 2.0 см. этот ответ SO

...