모든 하위 도메인, 포트 및 프로토콜에 CORS를 사용하려고합니다.
예를 들어 http://sub.mywebsite.com:8080/ 에서 https://www.mywebsite.com/으로 XHR 요청을 실행할 수 있기를 원합니다. *
일반적으로 원점 일치 요청을 활성화하고 싶습니다 (및 제한).
//*.mywebsite.com:*/*
모든 하위 도메인, 포트 및 프로토콜에 CORS를 사용하려고합니다.
예를 들어 http://sub.mywebsite.com:8080/ 에서 https://www.mywebsite.com/으로 XHR 요청을 실행할 수 있기를 원합니다. *
일반적으로 원점 일치 요청을 활성화하고 싶습니다 (및 제한).
//*.mywebsite.com:*/*
답변:
DaveRandom의 답변을 바탕으로 , 나는 또한 Access-Control-Allow-Origin
재 작성 규칙을 사용하지 않고 동일한 결과 ( 현재 특정 프로토콜 + 도메인 + 포트로 동적으로 설정 됨)를 생성하는 약간 더 간단한 Apache 솔루션을 발견했습니다 .
SetEnvIf Origin ^(https?://.+\.mywebsite\.com(?::\d{1,5})?)$ CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN
Header merge Vary "Origin"
그리고 그게 다야.
모든 하위 도메인 외에 상위 도메인 (예 : mywebsite.com)에서 CORS를 활성화하려는 사용자는 첫 번째 줄의 정규 표현식을 다음과 같이 간단히 바꿀 수 있습니다.
^(https?://(?:.+\.)?mywebsite\.com(?::\d{1,5})?)$
.
참고 : 사양 준수 및 올바른 캐싱 동작을 Vary: Origin
위해 비 CORS 요청 및 허용되지 않은 출처의 요청에 대해서도 CORS 지원 리소스에 대한 응답 헤더를 항상 추가 하십시오 ( 예제 참조 ).
//
Apache conf는 슬래시로 구분 된 정규 표현식을 사용하지 않기 때문에이 문맥에서 벗어날 필요 가 없습니다. Regexr은 슬래시가 구분 기호로 특별한 의미를 갖기 때문에 불평합니다.
The 'Access-Control-Allow-Origin' header contains multiple values '^(https?://(?:.+.)?aerofotea.com(?::d{1,5})?)$', but only one is allowed. Origin 'http://local.aerofotea.com' is therefore not allowed access.
CORS 사양은 전부 또는 아무것도 아닙니다. 그것은 단지 지원 *
, null
또는 정확한 프로토콜 + 도메인 + 포트 : http://www.w3.org/TR/cors/#access-control-allow-origin-response-header
서버는 정규식을 사용하여 오리진 헤더의 유효성을 검사해야하며 Access-Control-Allow-Origin 응답 헤더에서 오리진 값을 에코 할 수 있습니다.
편집 : 이 대신 @Noyo의 솔루션을 사용하십시오 . 로드시 더 단순하고 명확하며 성능이 훨씬 뛰어납니다.
역사적 목적만을위한 오리지널 답변 왼쪽.
나는이 문제를 해결하고 Apache와 작동하는 재사용 가능한 .htaccess (또는 httpd.conf) 솔루션을 생각해 냈습니다.
<IfModule mod_rewrite.c>
<IfModule mod_headers.c>
# Define the root domain that is allowed
SetEnvIf Origin .+ ACCESS_CONTROL_ROOT=yourdomain.com
# Check that the Origin: matches the defined root domain and capture it in
# an environment var if it does
RewriteEngine On
RewriteCond %{ENV:ACCESS_CONTROL_ROOT} !=""
RewriteCond %{ENV:ACCESS_CONTROL_ORIGIN} =""
RewriteCond %{ENV:ACCESS_CONTROL_ROOT}&%{HTTP:Origin} ^([^&]+)&(https?://(?:.+?\.)?\1(?::\d{1,5})?)$
RewriteRule .* - [E=ACCESS_CONTROL_ORIGIN:%2]
# Set the response header to the captured value if there was a match
Header set Access-Control-Allow-Origin %{ACCESS_CONTROL_ORIGIN}e env=ACCESS_CONTROL_ORIGIN
</IfModule>
</IfModule>
그냥 설정 ACCESS_CONTROL_ROOT
루트 도메인에 블록의 상단에 변수를 그리고 그것은 메아리 Origin:
에서 클라이언트에 요청 헤더 값 다시 Access-Control-Allow-Origin:
는 도메인과 일치하는 경우 응답 헤더 값을.
참고 또한 당신이 사용할 수 sub.mydomain.com
는 AS ACCESS_CONTROL_ROOT
그것은에 기원을 제한합니다 sub.mydomain.com
및 *.sub.mydomain.com
(도메인 루트가 될 필요가 없습니다 그것을 즉). 변경 가능한 요소 (프로토콜, 포트)는 정규식의 URI 일치 부분을 수정하여 제어 할 수 있습니다.
허용 된 답변을 따라갈 수 없기 때문에이 질문에 대답하고 있습니다.
예를 들어 http://mywebsite.com에 CORS 헤더를 보내지 않지만 http://somedomain.mywebsite.com/에 대해서는 작동합니다 .
SetEnvIf Origin "http(s)?://(.+\.)?mywebsite\.com(:\d{1,5})?$" CORS=$0
Header set Access-Control-Allow-Origin "%{CORS}e" env=CORS
Header merge Vary "Origin"
사이트를 활성화하려면 위의 Apache 구성에서 "mywebsite.com"대신 사이트를 배치하면됩니다.
여러 사이트를 허용하려면
SetEnvIf Origin "http(s)?://(.+\.)?(othersite\.com|mywebsite\.com)(:\d{1,5})?$" CORS=$0
배포 후 테스트 :
다음 컬 응답에는 변경 후 "Access-Control-Allow-Origin"헤더가 있어야합니다.
curl -X GET -H "Origin: http://examplesite1.com" --verbose http://examplesite2.com/query
PHP 전용 솔루션이 필요했기 때문에 누군가가 필요로하는 경우를 대비하여. "* .example.com"과 같은 허용 된 입력 문자열을 사용하고 입력이 일치하면 요청 헤더 서버 이름을 반환합니다.
function getCORSHeaderOrigin($allowed, $input)
{
if ($allowed == '*') {
return '*';
}
$allowed = preg_quote($allowed, '/');
if (($wildcardPos = strpos($allowed, '*')) !== false) {
$allowed = str_replace('*', '(.*)', $allowed);
}
$regexp = '/^' . $allowed . '$/';
if (!preg_match($regexp, $input, $matches)) {
return 'none';
}
return $input;
}
다음은 phpunit 데이터 제공자의 테스트 사례입니다.
// <description> <allowed> <input> <expected>
array('Allow Subdomain', 'www.example.com', 'www.example.com', 'www.example.com'),
array('Disallow wrong Subdomain', 'www.example.com', 'ws.example.com', 'none'),
array('Allow All', '*', 'ws.example.com', '*'),
array('Allow Subdomain Wildcard', '*.example.com', 'ws.example.com', 'ws.example.com'),
array('Disallow Wrong Subdomain no Wildcard', '*.example.com', 'example.com', 'none'),
array('Allow Double Subdomain for Wildcard', '*.example.com', 'a.b.example.com', 'a.b.example.com'),
array('Don\'t fall for incorrect position', '*.example.com', 'a.example.com.evil.com', 'none'),
array('Allow Subdomain in the middle', 'a.*.example.com', 'a.bc.example.com', 'a.bc.example.com'),
array('Disallow wrong Subdomain', 'a.*.example.com', 'b.bc.example.com', 'none'),
array('Correctly handle dots in allowed', 'example.com', 'exampleXcom', 'none'),
preg_quote()
올바른 방법이기 때문에 사용하도록 편집 됨 ( .
DNS 이름에 유효한 정규 표현식 메타 문자 preg_quote()
none
사양에 따라 헤더에 대해 의미 적으로 유효한 값이 아니거나 (또는 적어도 의미하는 바를 수행하지 않음) 명확히해야합니다 . 따라서 return null;
해당 분기에 대해 더 의미가있을 수 있으며이 경우 클라이언트에 헤더를 보내면 안되므로 호출자가 확인해야합니다.
preg_quote()
* 기호를 인용하므로 str_replace()
예를 들어 고아 "\"를 남깁니다.
Access-Control-Allow-Origin
.htaccess에서 설정하면 다음 작업 만 수행되었습니다.
SetEnvIf Origin "http(s)?://(.+\.)?domain\.com(:\d{1,5})?$" CRS=$0
Header always set Access-Control-Allow-Origin "%{CRS}e" env=CRS
나는 여러 가지 다른 제안 키워드를 시도 Header append
, Header set
, 아무도 일하지 키워드가 오래된 또는 유효하지 않은 경우 내가 아무 생각이 없지만, SO에 많은 답변에 제안 의 nginx .
내 완전한 해결책은 다음과 같습니다.
SetEnvIf Origin "http(s)?://(.+\.)?domain\.com(:\d{1,5})?$" CRS=$0
Header always set Access-Control-Allow-Origin "%{CRS}e" env=CRS
Header merge Vary "Origin"
Header always set Access-Control-Allow-Methods "GET, POST"
Header always set Access-Control-Allow-Headers: *
# Cached for a day
Header always set Access-Control-Max-Age: 86400
RewriteEngine On
# Respond with 200OK for OPTIONS
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
"쿠키 도메인"(www.domain.tld)에서 글꼴을 읽을 때 정적 "쿠키가없는"도메인에서 Font Awesome과 비슷한 문제가 발생했으며이 게시물이 우리의 영웅이었습니다. 여기를 참조하십시오 : 어떻게 '누락 간 리소스 공유 (CORS) 응답 헤더'webfont 문제를 해결할 수 있습니까?
copy / paste-r 유형 (및 소품을 제공하기 위해)에 대해서는 모든 기부금에서 이것을 모아서 사이트 루트의 .htaccess 파일 맨 위에 추가했습니다.
<IfModule mod_headers.c>
<IfModule mod_rewrite.c>
SetEnvIf Origin "http(s)?://(.+\.)?(othersite\.com|mywebsite\.com)(:\d{1,5})?$" CORS=$0
Header set Access-Control-Allow-Origin "%{CORS}e" env=CORS
Header merge Vary "Origin"
</IfModule>
</IfModule>
매우 안전하고 우아합니다. 그것을 좋아하십시오 : 당신은 자원 도둑 / 핫 링크 유형의 서버 대역폭을 열 필요가 없습니다.
소품 : @Noyo @DaveRandom @ pratap-koritala
(이 답변을 수락 된 답변에 대한 의견으로 남기려고했지만 아직 그렇게 할 수는 없습니다)
들어 봄 부팅 나는이 발견 RegexCorsConfiguration
공식을 확장하는을 CorsConfiguration
: https://github.com/looorent/spring-security-jwt/blob/master/src/main/java/be/looorent/security/jwt/RegexCorsConfiguration.java
원래 답변은 Apache 2.4 이전의 답변이었습니다. 그것은 나를 위해 작동하지 않았다. 다음은 2.4에서 작동하도록 변경 한 내용입니다. 이것은 yourcompany.com 의 모든 하위 도메인에 적용 됩니다.
SetEnvIf Host ^((?:.+\.)*yourcompany\.com?)$ CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin %{REQUEST_SCHEME}e://%{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN
Header merge Vary "Origin"
고아 가 정규식에서 끝나서 실제 호스트 (프로토콜 또는 포트에주의를 기울이지 않음) 만 비교 하기 위해 Lars의 답변을 약간 수정 \
해야했으며 localhost
프로덕션 도메인 이외의 도메인 을 지원하고 싶었습니다 . 따라서 $allowed
매개 변수를 배열로 변경했습니다 .
function getCORSHeaderOrigin($allowed, $input)
{
if ($allowed == '*') {
return '*';
}
if (!is_array($allowed)) {
$allowed = array($allowed);
}
foreach ($allowed as &$value) {
$value = preg_quote($value, '/');
if (($wildcardPos = strpos($value, '\*')) !== false) {
$value = str_replace('\*', '(.*)', $value);
}
}
$regexp = '/^(' . implode('|', $allowed) . ')$/';
$inputHost = parse_url($input, PHP_URL_HOST);
if ($inputHost === null || !preg_match($regexp, $inputHost, $matches)) {
return 'none';
}
return $input;
}
다음과 같이 사용법 :
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: " . getCORSHeaderOrigin(array("*.myproduction.com", "localhost"), $_SERVER['HTTP_ORIGIN']));
}