是否有一种方法允许多个跨域使用Access-Control-Allow-Origin头?

我知道*,但它太开放了。我只讲几个域。

举个例子,是这样的:

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

我已经尝试了上面的代码,但它似乎不能在Firefox中工作。

是否可以指定多个域,还是只能指定一个域?


当前回答

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

其他回答

这是我为一个被AJAX请求的PHP应用程序所做的

$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头的值,而不是返回*通配符。

也许我错了,但据我所知,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 ]
                  ; <scheme>, <host>, <port> productions from RFC3986

由此,我认为不同的起源是被承认的,并且应该被空间分隔开。

我有https://stackoverflow.com/a/7454204/13779574这段代码工作得很好,但当用户进入该页面时给出一个错误。 我用这段代码解决了这个问题。

if (isset($_SERVER['HTTP_ORIGIN'])) {
   $http_origin = $_SERVER['HTTP_ORIGIN'];
   if ($http_origin == "http://localhost:3000" || $http_origin == "http://api.loc/"){  
      header("Access-Control-Allow-Origin: $http_origin");
   }
}

下面是一个Java web应用的解决方案,基于yesthatguy的回答。

我使用的是Jersey REST 1.x

配置web.xml以识别Jersey REST和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>

下面是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;
    }
}

对于安装了URL重写2.0模块的iis7.5 +,请参阅此SO答案