Frage

Gibt es eine Möglichkeit, mehr Quer Domänen mit dem Access-Control-Allow-Origin Header zu ermöglichen?

Ich bin mir bewusst, die *, aber es ist zu offen. Ich möchte wirklich nur ein paar Domains ermöglichen.

Als Beispiel so etwas wie folgt aus:

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

Ich habe den obigen Code versucht, aber es scheint nicht in Firefox zu arbeiten.

Ist es möglich, mehrere Domänen angeben, oder bin ich mit nur stecken ein?

War es hilfreich?

Lösung

Klingt wie der empfohlene Weg, es zu tun, ist der Server die Herkunft haben Header des Clients zu lesen, zu vergleichen, dass in die Liste der Domains, die Sie erlauben möchten, und wenn es passt, Echo den Wert des Origin Header zurück an den Client als Access-Control-Allow-Origin Header in der Antwort.

Mit .htaccess können Sie es wie folgt tun:

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

Andere Tipps

Eine andere Lösung, die ich bin 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");
}

Das funktioniert für mich:

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

Wenn in .htaccess setzt, wird es sicher funktionieren.

ich das gleiche Problem mit woff-Fonts hatte, mehr Sub-Domains hatte Zugang zu haben. Damit Subdomains Ich habe so etwas zu meiner 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>

Für mehrere Domänen Sie könnten nur die Regex in SetEnvIf ändern.

Hier ist, wie die Origin-Header zurück Echo, wenn es Ihre Domain mit Nginx übereinstimmt, ist dies nützlich, wenn Sie eine Schriftart mehr Sub-Domains dienen wollen:

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

Hier ist, was ich für eine PHP-Anwendung hat, die von AJAX angefordert wird

$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);
}

Wenn der anfragende Ursprung von meinem Server erlaubt ist, geben Sie die $http_origin selbst als Wert des Access-Control-Allow-Origin Header stattdessen eine * Wildcard zurückzukehren.

Es ist ein Nachteil, Sie sollten sich bewusst sein: sobald wie Sie out-Quelldateien in ein CDN (oder einem anderen Server, die nicht Scripting erlaubt), oder wenn Sie Ihre Dateien auf einem Proxy-Cache gespeichert werden, Gang zu verändern, basierend auf 'Origin' request-Header wird nicht funktionieren.

Für mehrere Domänen, in Ihrem .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>

Für Nginx Benutzer CORS für mehrere Domänen zu ermöglichen. Ich mag das @ Marshalls Beispiel obwohl seine Anwers nur eine Domäne übereinstimmt. Um eine Liste der Domain übereinstimmen und Sub-Domain diese regex machen es erleichtern mit Schriften arbeiten:

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

Dies wird nur echo "Access-Control-Allow-Origin" Header, die mit der gegebenen Liste von Domains übereinstimmt.

Für IIS 7.5+ mit URL Rewrite 2.0-Modul installiert bitte sehen diese SO beantworten

Hier ist eine Lösung für Java-Web-App, basierend die Antwort von yesthatguy.

Ich verwende Jersey REST 1.x

Konfigurieren Sie die web.xml bewusst sein Jersey REST und die CORSResponseFilter

 <!-- Jersey REST config -->
  <servlet>    
    <servlet-name>JAX-RS Servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param> 
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
      <param-value>com.your.package.CORSResponseFilter</param-value>
    </init-param>   
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.your.package</param-value>
    </init-param>        
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/ws/*</url-pattern>
  </servlet-mapping>

Hier ist der Code für 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<String> allowedOrigins = new HashSet<String>(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;
}

}

Wie oben erwähnt, sollte Access-Control-Allow-Origin eindeutig sein und Vary sollte so eingestellt werden, Origin, wenn Sie hinter einem CDN (Content Delivery Network) sind.

Relevante Teil meiner Nginx Konfiguration:

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

Vielleicht bin ich falsch, aber so weit ich sehen kann Access-Control-Allow-Origin einen "origin-list" als Parameter hat.

Mit dem Definition ein origin-list ist:

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

Und von dieser, ich argumentiere unterschiedliche Herkunft zugelassen ist, und soll Leerzeichen getrennt .

Ich kämpfte dies für eine Domain einzurichten HTTPS ausgeführt wird, so dass ich dachte ich die Lösung teilen würde. Früher habe ich die folgende Anweisung in meiner httpd.conf Datei:

    <FilesMatch "\.(ttf|otf|eot|woff)$">
            SetEnvIf Origin "^http(s)?://(.+\.)?example\.com$" AccessControlAllowOrigin=$0
            Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    </FilesMatch>

Ändern example.com auf Ihren Domain-Namen. Fügen Sie diese innerhalb <VirtualHost x.x.x.x:xx> in der httpd.conf Datei. Beachten Sie, dass, wenn Ihr VirtualHost einen Port Suffix (zB :80), dann wird diese Richtlinie auf HTTPS nicht anwenden, so dass Sie auch gehen müssen / etc / apache2 / sites-available / default-ssl und fügen Sie die gleiche Richtlinie in dieser Datei innerhalb des <VirtualHost _default_:443> Abschnitt.

Sobald die Konfigurationsdateien aktualisiert werden, müssen Sie die folgenden Befehle im Terminal auszuführen:

a2enmod headers
sudo service apache2 reload

Wenn Sie Probleme mit Schriften, zu verwenden:

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

Für Express.js Anwendungen können Sie:

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();
});

HTTP_ORIGIN wird nicht von allen Browsern verwendet. Wie sicher ist HTTP_ORIGIN? Für mich ist es leer aus in FF kommt.
Ich habe die Seiten, die ich Zugriff auf meine Website erlauben, eine Site-ID senden über, ich meine DB dann mit dieser ID für den Datensatz prüfen und den SITE_URL Spaltenwert erhalten (www.yoursite.com).

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

Auch wenn die Sende über eine gültige Site-ID muss die Anforderung von der Domäne in meinem DB mit dieser Site-ID zugeordnet aufgeführt sind.

Hier ist eine erweiterte Option für Apache, das einige der neuesten und geplante Schriftdefinitionen enthält:

<FilesMatch "\.(ttf|otf|eot|woff|woff2|sfnt|svg)$">
    <IfModule mod_headers.c>
        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
    </IfModule>
</FilesMatch>

Und noch eine Antwort in Django. Um eine einheitliche Sicht zu haben CORS aus mehreren Domänen erlauben, hier ist mein Code:

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

Für ein ziemlich einfaches Kopieren / Einfügen für .NET-Anwendungen, schrieb ich diesen CORS zu ermöglichen, von innerhalb einer Datei global.asax. Dieser Code folgt dem Rat in der derzeit akzeptierte Antwort gegeben, was auch immer der Ursprung zurück in der Anforderung in die Antwort gegeben. Dadurch wird erreicht, effektiv ‚*‘, ohne es zu benutzen. Der Grund dafür ist, dass es mehrere andere CORS-Funktionen, einschließlich der Fähigkeit ermöglicht eine AJAX XMLHttpRequest mit dem ‚withCredentials‘ Attribute auf ‚true‘.

senden
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" , "*");
    }
}

Um mehr Domain-Zugang für einen ASMX-Dienst zu erleichtern, habe ich diese Funktion in der Datei 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();
    }
}

Dies ermöglicht CORS für auch von OPTIONS Verb Handhabung.

PHP-Code Beispiel für Sub-Domains entspricht.

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

Ein flexiblerer Ansatz ist Apache 2.4 der Ausdrücke zu verwenden. Sie können gegen Domänen, Wege, passen und fast jede andere Anforderung variabel. Obwohl die Antwort für alle * ist, empfängt die einzigen Anforderer diese Antwort sind diejenigen, die die Anforderungen ohnehin erfüllen.

<IfModule mod_headers.c>
    <If "%{HTTP:Host} =~ /\\bcdndomain\\.example$/i && %{HTTP:Origin} =~ /\\bmaindomain\\.example$/i">
        Header set Access-Control-Allow-Origin "*"
    </If>
</IfModule>

Google-Support Antwort auf Anzeigen über SSL dient, und die Grammatik in der RFC selbst , um anzuzeigen scheint, dass Sie Raum, um die URLs begrenzen können. Nicht sicher, wie gut unterstützt diese in verschiedenen Browsern ist.

Wenn Sie so viele Code-Beispiele, wie ich versuchen, es zu machen arbeitet CORS, ist es wert zu erwähnen, dass Sie Ihren Cache löschen müssen zuerst versuchen, wenn es tatsächlich funktioniert, ähnlich zu Themen wie, wenn alte Bilder sind noch vorhanden, auch wenn es auf dem Server gelöscht (weil es immer noch im Cache gespeichert wird).

Zum Beispiel CTRL + SHIFT + DEL in Google Chrome Ihren Cache zu löschen.

Das half mir mit diesem Code nach vielen reinen .htaccess Lösungen versuchen, und dies schien die einzige Arbeit (zumindest für mich):

    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>

Beachten Sie auch, dass es weit verbreitet ist verbreitet, dass viele Lösungen sagen Sie Header set ... geben, aber es ist Header add .... Hoffe, das hilft, wie ich jetzt jemand die gleichen Probleme für einige Stunden zu müssen.

Unter Antwort ist spezifisch für C #, aber das Konzept sollte auf alle verschiedenen Plattformen anwendbar sein.

Um Kreuz Herkunft Anfragen von einem Web-api zu ermöglichen, müssen Sie Option Anforderungen an Ihre Anwendung ermöglichen und unter Anmerkung auf Controller-Ebene hinzufügen.

[EnableCors (urlString, Kopfzeile, Method)] Nun können die Ursprünge nur ein s-String übergeben werden. SO, wenn Sie mehr als eine URL in der Anforderung als ein Komma getrennt Wert übergeben übergeben werden sollen.

urlString = „ https: //a.hello.com,https: //b.hello.com "

Nur ein einziger Ursprung kann für die Access-Control-Allow-Origin-Header angegeben werden. Aber man kann den Ursprung in Ihrer Antwort entsprechend der Anfrage. Vergessen Sie auch nicht einstellen die Vary-Header. In PHP würde ich Folgendes tun:

    /**
     * Enable CORS for the passed origins.
     * Adds the Access-Control-Allow-Origin header to the response with the origin that matched the one in the request.
     * @param array $origins
     * @return string|null returns the matched origin or null
     */
    function allowOrigins($origins)
    {
        $val = $_SERVER['HTTP_ORIGIN'] ?? null;
        if (in_array($val, $origins, true)) {
            header('Access-Control-Allow-Origin: '.$val);
            header('Vary: Origin');

            return $val;
        }

        return null;
    }

  if (allowOrigins(['http://localhost', 'https://localhost'])) {
      echo your response here, e.g. token
  }

Wir können auch diesen Satz in Global.asax-Datei für Asp.net Anwendung.

protected void Application_BeginRequest(object sender, EventArgs e)
    {

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

    }

Die Antwort scheint die Header mehr als einmal zu verwenden zu sein. Das heißt, anstatt das Senden

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

senden

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

Auf Apache, können Sie dies in einem httpd.conf <VirtualHost> Abschnitt oder .htaccess Datei mit mod_headers und dieser 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"

Der Trick ist add zu verwenden, anstatt append als erstes Argument.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top