Access-Control-Allow-Origin Domini di origine multipli?

Esiste un modo per consentire più domini incrociati utilizzando l’intestazione Access-Control-Allow-Origin ?

Sono a conoscenza del * , ma è troppo aperto. Voglio davvero concedere solo un paio di domini.

Ad esempio, qualcosa di simile:

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

Ho provato il codice sopra ma non sembra funzionare in Firefox.

È ansible specificare più domini o sono bloccato con uno solo?

Sembra che il modo migliore per farlo sia far leggere al tuo server l’intestazione Origin dal client, confrontarlo con l’elenco di domini che desideri consentire e, se corrisponde, redirect il valore dell’intestazione Origin al client come intestazione Access-Control-Allow-Origin nella risposta.

Con .htaccess puoi farlo in questo modo:

 # ---------------------------------------------------------------------- # 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   

Un’altra soluzione che sto usando in 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"); } 

Questo ha funzionato per me:

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

Quando viene inserito .htaccess , funzionerà sicuramente.

Ho avuto lo stesso problema con i caratteri woff, più sottodomini dovevano avere accesso. Per consentire sottodomini ho aggiunto qualcosa di simile al mio httpd.conf:

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

Per più domini è ansible modificare la regex in SetEnvIf .

Ecco come far risuonare l’intestazione Origin se corrisponde al tuo dominio con Nginx, questo è utile se vuoi servire un sottoinsieme di caratteri multipli:

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

Ecco cosa ho fatto per un’applicazione PHP richiesta da 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); } 

Se l’origine della richiesta è consentita dal mio server, restituire $http_origin come valore dell’intestazione Access-Control-Allow-Origin invece di restituire un carattere jolly * .

C’è uno svantaggio di cui dovresti essere a conoscenza: non appena estrai i file su un CDN (o qualsiasi altro server che non consente lo scripting) o se i tuoi file sono memorizzati nella cache su un proxy, modificando la risposta in base a “Origin” l’intestazione della richiesta non funzionerà.

Per più domini, nel tuo .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  

Per IIS 7.5+ con il modulo URL Rewrite 2.0 installato, vedere questa risposta SO

Per gli utenti Nginx per consentire CORS per più domini. Mi piace l’esempio di @ marshall, anche se le sue anwers corrispondono solo a un dominio. Per abbinare un elenco di domini e sottodomini questa regex facilita il lavoro con i caratteri:

 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"; } } 

Verrà visualizzato solo l’intestazione “Access-Control-Allow-Origin” che corrisponde alla lista di domini fornita.

Ecco una soluzione per l’app Web Java, basata sulla risposta di yesthatguy.

Sto usando Jersey REST 1.x.

Configura il web.xml per essere a conoscenza di Jersey REST e 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/*  

Ecco il codice per 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; } } 

Come accennato in precedenza, Access-Control-Allow-Origin dovrebbe essere univoco e Vary dovrebbe essere impostato su Origin se si è dietro un CDN (Content Delivery Network).

Parte pertinente della mia configurazione 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'; } 

Forse ho torto, ma per quanto posso vedere Access-Control-Allow-Origin ha un "origin-list" come parametro.

Per definizione, una 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 

E da questo, sostengo che diverse origini sono ammesse e dovrebbero essere separate dallo spazio .

Ho faticato a configurarlo per un dominio che eseguiva HTTPS, quindi ho pensato di condividere la soluzione. Ho usato la seguente direttiva nel mio file httpd.conf :

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

Cambia example.com con il tuo nome di dominio. Aggiungi questo all’interno di nel tuo file httpd.conf . Nota che se il tuo VirtualHost ha un suffisso di porta (es :80 ), allora questa direttiva non si applicherà a HTTPS, quindi dovrai anche andare a / etc / apache2 / sites-available / default-ssl e aggiungere la stessa direttiva in quel file, all’interno della sezione .

Una volta aggiornati i file di configurazione, sarà necessario eseguire i seguenti comandi nel terminale:

 a2enmod headers sudo service apache2 reload 

Se hai problemi con i font, usa:

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

HTTP_ORIGIN non è utilizzato da tutti i browser. Quanto è sicuro HTTP_ORIGIN? Per me è vuoto in FF.
Ho i siti che autorizzo l’accesso al mio sito tramite un ID sito, quindi controllo il mio DB per la registrazione con quell’ID e ottengo il valore della colonna SITE_URL (www.yoursite.com).

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

Anche se l’invio su un ID sito valido, la richiesta deve provenire dal dominio elencato nel mio DB associato all’ID sito.

Ecco un’opzione espansa per Apache che include alcune delle definizioni di font più recenti e pianificate:

   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   

E un’altra risposta in Django. Per avere una singola vista che consente CORS da più domini, ecco il mio codice:

 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 

Per facilitare l’accesso a più domini per un servizio ASMX, ho creato questa funzione nel file 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(); } } 

Ciò consente la gestione CORS del verbo OPTIONS anche.

La risposta del supporto di Google sul servire annunci su SSL e la grammatica nella stessa RFC sembra indicare che è ansible delimitare lo spazio degli URL. Non sei sicuro di quanto sia ben supportato in diversi browser.

Se provi tanti esempi di codice come me per farlo funzionare usando CORS, vale la pena menzionare che devi prima svuotare la cache per provare se effettivamente funziona, similmente a problemi come quando le vecchie immagini sono ancora presenti, anche se è cancellato sul server (perché è ancora salvato nella cache).

Ad esempio CTRL + MAIUSC + CANC in Google Chrome per eliminare la cache.

Questo mi ha aiutato a usare questo codice dopo aver provato molte soluzioni .htaccess pure e questo sembrava l’unico che funzionasse (almeno per me):

  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   

Nota anche che è molto diffuso che molte soluzioni dicono che devi digitare Header set ... ma è Header add ... Spero che questo aiuti qualcuno che ha gli stessi problemi da qualche ora come me.

Per una copia / incolla abbastanza semplice per le applicazioni .NET, l’ho scritto per abilitare CORS all’interno di un file global.asax. Questo codice segue il consiglio dato nella risposta attualmente accettata, che riflette l’origine della risposta nella richiesta. Questo effettivamente raggiunge ‘*’ senza usarlo. La ragione di ciò è che abilita molte altre funzionalità di CORS, inclusa la possibilità di inviare un XMLHttpRequest AJAX con l’attributo ‘withCredentials’ impostato su ‘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" , "*"); } } 

Un approccio più flessibile consiste nell’utilizzare le espressioni di Apache 2.4. Puoi abbinare domini, percorsi e praticamente ogni altra variabile richiesta. Sebbene la risposta sia * per tutti, gli unici richiedenti che ricevono quella risposta sono quelli che soddisfano comunque i requisiti.

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

Esempio di codice PHP per la corrispondenza dei sottodomini.

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

La risposta sembra essere quella di usare l’intestazione più di una volta. Cioè, piuttosto che inviare

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

inviare

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

Su Apache, puoi farlo in una sezione httpd.conf o in un file .htaccess usando mod_headers e questa syntax:

 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" 

Il trucco è usare add piuttosto che append come primo argomento.

Possiamo anche impostarlo nel file Global.asax per l’applicazione Asp.net.

 protected void Application_BeginRequest(object sender, EventArgs e) { // enable CORS HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "https://www.youtube.com"); }