Access-Control-Allow-Origin Несколько доменов происхождения?

Есть ли способ разрешить использование нескольких кросс-доменов с помощью заголовка Access-Control-Allow-Origin ?

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

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

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

Я пробовал вышеуказанный код, но он не работает в Firefox.

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

    26 Solutions collect form web for “Access-Control-Allow-Origin Несколько доменов происхождения?”

    Похоже, что рекомендуемый способ сделать это, чтобы ваш сервер прочитал заголовок Origin от клиента, сравните это со списком доменов, которые вы хотите разрешить, и если он совпадает, повторите значение заголовка Origin обратно клиенту как заголовок Access-Control-Allow-Origin в ответе.

    С .htaccess вы можете сделать это следующим образом:

     # ---------------------------------------------------------------------- # Allow loading of external fonts # ----------------------------------------------------------------------   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   

    Другое решение, которое я использую в 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"); } 

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

     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 , он будет работать точно.

    У меня была та же проблема с woff-fonts, у нескольких субдоменов был доступ. Чтобы разрешить субдомены, я добавил что-то вроде этого в httpd.conf:

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

    Для нескольких доменов вы можете просто изменить регулярное выражение в SetEnvIf .

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

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

    Вот что я сделал для приложения 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 вместо того, чтобы возвращать подстановочный символ * .

    Существует один недостаток, о котором вам следует знать: как только вы выберете исходные файлы на CDN (или на любой другой сервер, который не позволяет создавать скрипты), или если ваши файлы кэшируются на прокси, изменяя ответ на основе «Origin», заголовок запроса не будет работать.

    Для нескольких доменов в вашем .htaccess :

      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  

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

    Для пользователей 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», которые соответствуют указанному списку доменов.

    Вот решение для веб-приложения Java, основанного на ответе от yesthatguy.

    Я использую Jersey REST 1.x

    Настройте web.xml, чтобы знать о Джерси REST и CORSResponseFilter

        JAX-RS Servlet com.sun.jersey.spi.container.servlet.ServletContainer  com.sun.jersey.api.json.POJOMappingFeature true   com.sun.jersey.spi.container.ContainerResponseFilters com.your.package.CORSResponseFilter   com.sun.jersey.config.property.packages com.your.package  1   JAX-RS Servlet /ws/*  

    Вот код для CORSResponseFilter

     import com.sun.jersey.spi.container.ContainerRequest; import com.sun.jersey.spi.container.ContainerResponse; import com.sun.jersey.spi.container.ContainerResponseFilter; public class CORSResponseFilter implements ContainerResponseFilter{ @Override public ContainerResponse filter(ContainerRequest request, ContainerResponse response) { String[] allowDomain = {"http://localhost:9000","https://my.domain.example"}; Set allowedOrigins = new HashSet(Arrays.asList (allowDomain)); String originHeader = request.getHeaderValue("Origin"); if(allowedOrigins.contains(originHeader)) { response.getHttpHeaders().add("Access-Control-Allow-Origin", originHeader); response.getHttpHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true"); response.getHttpHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); } return response; } } 

    Как уже упоминалось выше, Access-Control-Allow-Origin должен быть уникальным, и Vary должен быть установлен в Origin если вы находитесь за CDN (Сеть доставки контента).

    Соответствующая часть моей конфигурации Nginx:

     if ($http_origin ~* (https?://.*\.mydomain.example(:[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'; } 

    Возможно, я ошибаюсь, но, насколько я вижу, Access-Control-Allow-Origin имеет параметр "origin-list" качестве параметра.

    По определению origin-list :

     origin = "origin" ":" 1*WSP [ "null" / origin-list ] origin-list = serialized-origin *( 1*WSP serialized-origin ) serialized-origin = scheme "://" host [ ":" port ] ; , ,  productions from RFC3986 

    И из этого, я утверждаю, что различное происхождение допускается и должно быть разделено пространством .

    Я изо всех сил пытался установить это для домена, работающего с HTTPS, поэтому я решил поделиться этим решением. Я использовал следующую директиву в файле httpd.conf :

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

    Измените example.com на свое доменное имя. Добавьте это внутри в ваш файл httpd.conf . Обратите внимание, что если ваш VirtualHost имеет суффикс порта (например :80 ), то эта директива не будет применяться к HTTPS, поэтому вам также нужно будет перейти в / etc / apache2 / sites-available / default-ssl и добавить ту же директиву в этом файла, внутри раздела .

    После обновления файлов конфигурации вам необходимо будет выполнить следующие команды в терминале:

     a2enmod headers sudo service apache2 reload 

    Если у вас возникли проблемы со шрифтами, используйте:

       Header set Access-Control-Allow-Origin "*"   

    HTTP_ORIGIN не используется всеми браузерами. Насколько безопасен HTTP_ORIGIN? Для меня это становится пустым в FF.
    У меня есть сайты, на которых я разрешаю доступ к моему сайту для отправки по идентификатору сайта, затем я проверяю свою БД для записи с этим идентификатором и получаю значение столбца SITE_URL (www.yoursite.com).

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

    Даже если отправка по допустимому идентификатору сайта требует запроса из домена, указанного в моей БД, связанной с этим идентификатором сайта.

    Вот расширенный вариант для apache, который включает в себя некоторые из последних и запланированных определений шрифтов:

       SetEnvIf Origin "^http(s)?://(.+\.)?(domainname1|domainname2|domainname3)\.(?:com|net|org)$" AccessControlAllowOrigin=$0$1$2 Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin Header set Access-Control-Allow-Credentials true   

    И еще один ответ в 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 

    Чтобы облегчить доступ к нескольким доменам для службы ASMX, я создал эту функцию в файле global.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 .

    Ответ поддержки Google на показ объявлений через SSL и грамматику в самом RFC , похоже, указывает на то, что вы можете разграничить URL-адреса. Не уверен, насколько хорошо это поддерживается в разных браузерах.

    Если вы попробуете так много примеров кода, как я, чтобы заставить его работать с помощью CORS, стоит упомянуть, что сначала нужно очистить кеш, чтобы попытаться, если он действительно работает, похожий на проблемы, например, когда старые изображения все еще присутствуют, даже если это удаляется на сервере (поскольку он все еще сохраняется в вашем кеше).

    Например, CTRL + SHIFT + DEL в Google 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"   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   

    Также обратите внимание, что широко распространено то, что многие решения говорят, что вам нужно набирать Header set ... но это Header add ... Надеюсь, что это помогает кому-то, испытывающему те же проблемы в течение нескольких часов, как я.

    Для довольно легкой копии / вставки для .NET-приложений я написал это, чтобы включить CORS из файла global.asax. Этот код следует рекомендациям, приведенным в принятом в настоящее время ответе, отражая то, что возвращается в запросе в ответ. Это эффективно позволяет «*» не использовать его. Причиной этого является то, что он позволяет использовать несколько других функций CORS, включая возможность отправки AJAX XMLHttpRequest с атрибутом ‘withCredentials’, установленным в ‘true’.

     void Application_BeginRequest(object sender, EventArgs e) { if (Request.HttpMethod == "OPTIONS") { Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); Response.AddHeader("Access-Control-Max-Age", "1728000"); Response.End(); } else { Response.AddHeader("Access-Control-Allow-Credentials", "true"); if (Request.Headers["Origin"] != null) Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]); else Response.AddHeader("Access-Control-Allow-Origin" , "*"); } } 

    Более гибкий подход заключается в использовании выражений Apache 2.4. Вы можете сопоставлять домены, пути и практически любую другую переменную запроса. Хотя ответ * для всех, единственные, кто получает этот ответ, соответствуют тем, которые в любом случае соответствуют требованиям.

       Header set Access-Control-Allow-Origin "*"   

    Пример кода PHP для сопоставления поддоменов.

     if( preg_match("/http:\/\/(.*?)\.yourdomain.example/", $_SERVER['HTTP_ORIGIN'], $matches )) { $theMatch = $matches[0]; header('Access-Control-Allow-Origin: ' . $theMatch); } 

    Ответ, похоже, заключается в использовании заголовка более одного раза. То есть вместо отправки

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

    Отправить

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

    В Apache вы можете сделать это в разделе httpd.conf или .htaccess с помощью mod_headers и этого синтаксиса:

     Header add Access-Control-Allow-Origin "http://domain1.example" Header add Access-Control-Allow-Origin "http://domain2.example" Header add Access-Control-Allow-Origin "http://domain3.example" 

    Трюк заключается в том, чтобы использовать вместо append в качестве первого аргумента команду add а не append .

    Мы также можем установить это в файле Global.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"); } 
    Давайте будем гением компьютера.