현재 번역은 완벽하지 않습니다. 한국어로 문서 번역에 동참해주세요.
처음 서브되는 리소스의 도메인과 다른 도메인으로부터 리소스가 요청될 경우 해당 리소스는 cross-origin HTTP 요청에 의해 요청됩니다. 예를 들어, https://domain-a.com으로부터 서브되는 HTML 페이지가 <img> src
속성을 통해 https://domain-b.com/image.jpg를 요청하는 경우가 있습니다. 오늘날 많은 웹 페이지들은 CSS 스타일시트, 이미지, 그리고 스크립트와 같은 리소스들을 각각의 출처로부터 읽어옵니다.
보안 상의 이유로, 브라우저들은 스크립트 내에서 초기화되는 cross-origin HTTP 요청을 제한합니다. 예를 드면, XMLHttpRequest는 same-origin 정책을 따르기에, XMLHttpRequest을 사용하는 웹 애플리케이션은 자신과 동일한 도메인으로 HTTP 요청을 보내는 것만 가능했습니다. 웹 애플리케이션을 개선시키기 위해, 개발자들은 브라우저 벤더사들에게 XMLHttpRequest가 cross-domain 요청을 할 수 있도록 요청했습니다
W3C Web Applications Working Group은 새로운 Cross-Origin Resource Sharing (CORS) 메커니즘을 권하고 있습니다. CORS는 웹 서버에게 보안 cross-domain 데이터 전송을 활성화하는 cross-domain 접근 제어권을 부여합니다. 모던 브라우저들은 cross-origin HTTP 요청의 위험성을 완화시키기 위해 (XMLHttpRequest와 같은) API 컨테이너 내에서 CORS를 사용합니다.
이 글은 웹 관리자, 서버 개발자 그리고 프로트엔드 개발자를 위한 것입니다. 모던 브라우저들은 헤더와 정책 집행을 포함하여, cross-origin 공유에 대한 클라이언트 측 컴포넌트를 다룹니다. 그러나, 이러한 새로운 표준은 서버가 새로운 요청 헤더와 응답 헤더를 반드시 처리해야 한다는 것을 의미합니다. 서버 개발자들에게는 서버 관점의 cross-origin sharing (PHP 코드 조각을 이용한)을 다루고 있는 다른 글들이 도움이 될 것입니다
이런 cross-origin 공유 표준은 다음과 같은 내용을 위해 cross-site HTTP 요청을 활성화하는데 사용됩니다:
- 위에서 거론한데로, cross-site의 방식 내에서의
XMLHttpRequest
API 호출 - (CSS 내 @font-face에서의 cross-domain 폰트 사용을 위한) 웹 폰트, 이 덕분에 서버들은 허용된 웹 사이트에서만 cross-site 하에 로드하고 사용할 수 TrueType 폰트들을 배포할 수 있습니다.
- 허용된 웹 사이트에서만 로딩되어 사용할 수 있도록 관리 배포되는 웹 폰트 (CSS
@font-face를 통한 C
ross-domain 폰트 사용) - WebGL 텍스쳐
- drawImage를 사용해 캔버스에 드로잉되는 이미지/비디오 프레임들.
- (CSSOM 접근을 위한) 스타일시트.
- (활성화된 예외 보고를 위한) 스크립트.
이 글은 Cross-Origin Resource Sharing에 대한 일반적인 논고이며, Firefox 3.5내에서 구현된 HTTP 헤더에 관해 논한 내용을 포함합니다.
개요
Cross-Origin Resource Sharing 표준은 웹 브라우저가 사용하는 정보를 읽을 수 있도록 허가된 출처 집합를 서버에게 알려주도록 허용하는 HTTP 헤더를 추가함으로써 동작합니다. 추가적으로, 사용자 데이터 상에서 부수 효과를 일으킬 수 있는 HTTP 요청 메서드에 대해(특히, GET
이외의 HTTP 메서드들 혹은 어떤 MIME 타입을 사용하는 POST
사용에 대해), 스펙은 브라우저가 요청을 "preflight"(사전 전달)하도록 강제하는데, 이는 HTTP OPTION
요청 메서드를 이용해 서버로부터 지원 중인 메서드들을 내려 받은 뒤, 서버에서 "approval"(승인) 시에 실제 HTTP 요청 메서드를 이용해 실제 요청을 전송하는 것을 말합니다. 서버들은 또한 클라이언트에게 (Cookie와 HTTP Authentication 데이터를 포함하는) "credentials"가 요청과 함께 전송되어야 하는지를 알려줄 수도 있습니다.
계속되는 섹션에서는 사용 중인 HTTP 헤더의 상세 내용뿐만 아니라, 시나리오에 대해서도 논하고 있습니다.
접근 제어 시나리오 예제
여기에 우리는 Cross-Origin Resource Sharing이 동작하는 방식에 대해 묘사하는 세 가지 시나리오를 보여주고 있습니다. 모든 예제는 지원되는 모든 브라우저에서 cross-site 요청에 사용될 수 있는 XMLHttpRequest
객체를 사용합니다.
섹션들에 포함되어 있는 자바스크립트 코드 조각(그리고 이런 cross-site 요청을 올바르게 처리하는 서버 코드의 실행 인스턴스)은 이 링크를 통해 "동작하는" 예제로 보실 수 있으며, cross-site XMLHttpRequest를
지원하는 브라우저에서 동작할 것입니다. (PHP 코드 조각을 포함하는)서버 관점의 Cross-Origin Resource Sharing 논고는 여기에서 보실 수 있습니다.
간단한 요청
간단한 cross-site 요청은 다음의 조건들에 모두 부합하는 것 중 하나입니다:
- 허용된 유일한 메서들은 다음과 같습니다:
GET
HEAD
POST
사용자
에이전트에 의해 자동으로 설정되는 헤더(Connection
,User-Agent
등)들을 제외하고, 수동 설정이 허용되는 유일한 헤더들은 다음과 같습니다:Accept
Accept-Language
Content-Language
Content-Type
- Content-Type 헤더에 대해 허용되는 유일한 값은 다음과 같습니다:
application/x-www-form-urlencoded
multipart/form-data
text/plain
예를 들어, https://foo.example
도메인 상의 웹 컨텐츠가 https://bar.other
도메인 상의 컨텐츠를 호출한다고 가정해보세요. "foo.example"에 배포되는 자바스크립트 내에서는 다음과 같은 분류의 코드가 사용될 수 있을 겁니다:
var invocation = new XMLHttpRequest(); var url = 'https://bar.other/resources/public-data/'; function callOtherDomain() { if(invocation) { invocation.open('GET', url, true); invocation.onreadystatechange = handler; invocation.send(); } }
이런 경우에 브라우저가 서버에 전송하게 될 내용, 그리고 서버가 응답하는 방식에 대해 알아보도록 하죠:
1: GET /resources/public-data/ HTTP/1.1 2: Host: bar.other 3: User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1. 9.1b3pre) Gecko/20081130 Minefield/3.1b3pre 4: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5: Accept-Language: en-us,en;q=0.5 6: Accept-Encoding: gzip,deflate 7: Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 8: Connection: keep-alive 9: Referer: https://foo.example/examples/access-control/simpleXSInvocation.html 10: Origin: https://foo.example 13: HTTP/1.1 200 OK 14: Date: Mon, 01 Dec 2008 00:23:53 GMT 15: Server: Apache/2.0.61 16: Access-Control-Allow-Origin: * 17: Keep-Alive: timeout=2, max=100 18: Connection: Keep-Alive 19: Transfer-Encoding: chunked 20: Content-Type: application/xml 21: 22: [XML Data]
1번째부터 10번째 줄까지는 Firefox 3.5에 의해 전달된 헤더입니다. 위 예에서 10번째 줄에 있는 Origin:
헤더가 해당 요청이 "https://foo.example
" 도메인에 있는 컨텐츠로부터 온 것이라는 것을 알려주는 중요한 HTTP 요청 헤더라는 것을 알아두시기 바라랍니다.
13번째부터 22번째 줄은 "https://bar.other
" 도메인의 서버에서 온 HTTP 응답을 보여주고 있습니다. 응답에서 보면, 서버는 16번째 줄에서 볼 수 있는 Access-Control-Allow-Origin:
헤더를 전달하고 있습니다. 이 예제에서의 Origin:
헤더와 Access-Control-Allow-Origin:
헤더의 사용은 그에 대한 가장 간단한 사용법 내의 접근 제어 프로토콜를 보여주고 있습니다. 위 경우에, 서버는 리소스가 cross-site 방식 내에서 모든 도메인으로부터 접근 가능하다는 것을 의미하는 "Access-Control-Allow-Origin: *
"와 함께 응답하고 있습니다. 만약 "https://bar.other
" 에 있는 리소스의 소유자가 리소스에 대한 접근을 https://foo.example
에게만 허용하길 바란다면, 다음과 같이 응답해야 합니다:
Access-Control-Allow-Origin: https://foo.example
이제, (10번째 줄과 같은 요청 내 헤더인 ORIGIN에 의해 식별된) https://foo.example
외에 어떤 다른 도메인도 cross-site 방식으로 리소스에 접근할 수 없다는 것을 알아두시기 바랍니다. Access-Control-Allow-Origin
헤더는 요청의 Origin
헤더를 통해 전송되었던 값을 포함해야 합니다.
사전 요청
(위에서 언급했던) 간단한 요청과 다르게, "preflighted"(사전 전달) 요청은 먼저, 실제 요청이 전송하기에 안전한지 아닌지를 결정하기 위해, 다른 도메인에 있는 리스스에 OPTION
메서드로 HTTP 요청을 전송합니다. Cross-site 요청은 사용자 데이터에 대한 함축적인 의미를 가지고 있기에 이와 같이 사전 전달됩니다. 특히, 다음과 같은 경우에 요청이 사전 전달됩니다:
GET
,HEAD
혹은POST
외의 메서드를 사용하는 경우. 또한POST
메서드를 사용한 요청이application/x-www-form-urlencoded
,multipart/form-data
, ortext/plain
이외의 다른 값을 가진 Content-Type과 함께 요청 데이터를 전송하는데 사용된 경우에 그렇습니다. 예를 들자면,POST
요청이 서버에application/xml
혹은text/xml
을 사용하여 XML 페이로드를 전송하게 되면, 요청은 사전 전달됩니다.- 요청 내에 커스텀 헤더를 설정한 경우(예를 들자면 요청이
X-PINGOTHER
와 같은 헤더를 사용하는 경우)
Note: Gecko 2.0부터, text/plain
, application/x-www-form-urlencoded
, 그리고 multipart/form-data
데이터 인코딩은 사전 전달없이 cross-site 요청을 전송할 수 있게 되었습니다.
다음은 이런 종류의 실행 예제입니다:
var invocation = new XMLHttpRequest(); var url = 'https://bar.other/resources/post-here/'; var body = '<?xml version="1.0"?><person><name>Arun</name></person>'; function callOtherDomain(){ if(invocation) { invocation.open('POST', url, true); invocation.setRequestHeader('X-PINGOTHER', 'pingpong'); invocation.setRequestHeader('Content-Type', 'application/xml'); invocation.onreadystatechange = handler; invocation.send(body); } } ......
위 예에서, 3번째 줄은 8번째에서 POST 요청과 함께 전송할 XM을 만들어 내고 있습니다. 또한, 9번째 줄에서, "customized" (비표준의) HTTP 요청 헤더이 설정되었습니다(X-PINGOTHER: pingpong
). 어떤 헤더들은 HTTP/1.1 프로토콜의 일부는 아니지만, 웹 애플리케이션에서 일반적으로 유용하게 사용됩니다. 요청(POST
)은 값이 application/xml
인 Content-Type을 사용하기에, 해당 요청은 사전 전달됩니다.
클라이언트와 서버 간의 전체적인 교환을 살펴보도록 하죠:
OPTIONS /resources/post-here/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: keep-alive Origin: https://foo.example Access-Control-Request-Method: POST Access-Control-Request-Headers: X-PINGOTHER HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:39 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: https://foo.example Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER Access-Control-Max-Age: 1728000 Vary: Accept-Encoding, Origin Content-Encoding: gzip Content-Length: 0 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain POST /resources/post-here/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: keep-alive X-PINGOTHER: pingpong Content-Type: text/xml; charset=UTF-8 Referer: https://foo.example/examples/preflightInvocation.html Content-Length: 55 Origin: https://foo.example Pragma: no-cache Cache-Control: no-cache <?xml version="1.0"?><person><name>Arun</name></person> HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:40 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: https://foo.example Vary: Accept-Encoding, Origin Content-Encoding: gzip Content-Length: 235 Keep-Alive: timeout=2, max=99 Connection: Keep-Alive Content-Type: text/plain [Some GZIP'd payload]
위에서 1번째부터 12번째 줄까지는 OPTIONS 메서드를 이용한 사전 전달 요청을 보여줍니다. Firefox 3.1은 위 자바스크립트 코드 조각이 사용하고 있었던 요청 파라메터에 근거하여 요청을 전송할 필요가 있다고 결정하기에, 서버는 실제 요청 파라메터를 이용한 요청 전송을 받아들일 수 있는지 여부에 대해 응답할 수 있습니다. OPTIONS는 서버로부터 전달되는 여분의 정보를 결정하는데 사용되며, 리소스를 변경하는데 사용될 수 없다는 것을 의미하는 멱등(idempotent) 메서드입니다. OPTIONS 요청과 함께, 두 개의 다른 요청이 (각각 11번째 줄과 12번째 줄에서) 전송되었다는 것을 알아두시기 바랍니다:
Access-Control-Request-Method: POST Access-Control-Request-Headers: X-PINGOTHER
Access-Control-Request-Method
헤더는 사전 전달 요청의 일부분으로, 실제 요청이 전달될 경우, POST
요청 메서드와 함께 전송될 것임을 서버에게 알려줍니다. Access-Control-Request-Headers
헤더는 실제 요청이 전달된 경우, X-PINGOTHER라는 커스텀 헤더와 함께 전송될 것임을 서버에게 알려줍니다. 이후 서버는 이런 환경 아래에서 요청을 받아들여야 하는지 아닌지를 결정하게 됩니다.
15번째부터 27번째 줄은 요청 메서드(POST
)와 요청 헤더(X-PINGOTHER
)를 받아들일 수 있다는 것을 가리키는 서버가 전송하는 응답입니다. 특히, 18번째부터 21번째 줄을 보시기 바랍니다:
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
서버는 Access-Control-Allow-Methods
와 함께 응답하며 POST, GET 그리고 OPTIONS가 리소스를 쿼리하기 위해 실행 가능한 메서드라고 알려줍니다. 이 헤더는 HTTP/1.1 Allow: 응답 헤더와 유사하지만, 접근 제어의 컨텍스트 사이에서 엄격하게 사용된다는 것을 알아두시기 바랍니다. 서버는 이것이 실제 요청과 함께 사용되도록 허가된 헤더인지 확인하는, Access-Control-Allow-Headers
를 X-PINGOTHER, Content-Type
이라는 값과 함께 전송합니다. Access-Control-Allow-Methods
처럼 Access-Control-Allow-Headers
도 쉼표로 구분된 수용 가능한 헤더들의 목록입니다.
마지막으로, Access-Control-Max-Age
은 사전 전달 요청에 대한 응답이 다른 사전 전달 요청을 전송하지 않고 얼마동안 캐시되어 있는지를 나타내는 초 단위 값을 전달합니다. 위 예제에서, 86400 초는 24시간을 말합니다. 각 브라우저는 Access-Control-Max-Age
가 더 큰 경우 우선권을 갖는 최대 인터벌 값을 가지고 있다는 것을 알아두시기 바랍니다.
인증을 이용한 요청
XMLHttpRequest와
접근 제어 모두에 의해 드러난 가장 흥미로운 능력은 HTTP 쿠키와 HTTP Authentication 정보를 알아차리는 "credentialed"(인증된) 요청을 만들어내는 능력입니다. 기본적으로, cross-site XMLHttpRequest
실행 내에서, 브라우저는 자격 증명을 위한 정보를 전송하지 않을 것입니다. 그것이 실행되면 특정 플래그가 XMLHttpRequest
객체에 설정되어야 합니다.
아래 예제에서, https://foo.example
로부터 초기에 로드된 컨텐츠는 쿠키를 설정하는 https://bar.other
에 있는 리소스에 대한 간단한 GET 요청을 만들어 내고 있습니다. foo.example의 컨텐츠는 다음과 비슷한 자바스크립트를 포함하고 있을 겁니다:
var invocation = new XMLHttpRequest(); var url = 'https://bar.other/resources/credentialed-content/'; function callOtherDomain(){ if(invocation) { invocation.open('GET', url, true); invocation.withCredentials = true; invocation.onreadystatechange = handler; invocation.send(); } }
7번째 줄은 쿠키와 함께 요청이 호출되도록 하려면 설정해야 하는 XMLHttpRequest
의 플래그, 즉 withCredentials
boolean 값을 보여줍니다. 기본적으로, 이 호출은 쿠키없이 진행됩니다. 이것은 간단한 GET
요청이기에 사전 전달되지 않으며, 브라우저는 Access-Control-Allow-Credentials: true
헤더를 갖고 있지 않은 응답은 어떤 것이든 거절할 것이며, 웹 컨텐츠 호출에 이용 가능한 응답을 일으키지 않을 겁니다.
다음은 클라이언트와 서버 간의 간단한 교환 내용입니다:
GET /resources/access-control-with-credentials/ HTTP/1.1 Host: bar.other User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: keep-alive Referer: https://foo.example/examples/credential.html Origin: https://foo.example Cookie: pageAccess=2 HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:34:52 GMT Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2 X-Powered-By: PHP/5.2.6 Access-Control-Allow-Origin: https://foo.example Access-Control-Allow-Credentials: true Cache-Control: no-cache Pragma: no-cache Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT Vary: Accept-Encoding, Origin Content-Encoding: gzip Content-Length: 106 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain [text/plain payload]
11번째 줄이 https://bar.other
에 있는 컨텐츠를 위해 정해져 있는 쿠키를 포함할지라도, bar.other가 (19번째 줄의) Access-Control-Allow-Credentials: true
와 함께 응답하지 않았다면, 응답은 무시되었을 것이며 웹 컨텐츠를 이용하지 못했을 겁니다. 중요한 사항: 인증된 요청에 응답하는 경우, 서버는 도메인을 특정해야만 하며, 와일드 카드를 사용할 수 없습니다. 위 예제는 헤더가 Access-Control-Allow-Origin: *
와 같이 와일드 카드 처리되었다면 실패했을 겁니다. Access-Control-Allow-Origin
헤더가 https://foo.example
을 명시하고 있기에, 웹 컨텐츠 호출에 자격 증명이 인식된(credentail-cognizant) 컨텐츠가 반환될 것입니다. 22번째 줄에서 더 많은 쿠키가 설정됐음을 알아두시기 바랍니다.
이 예제의 모든 내용은 여기에서 동작하는 예제로 보실 수 있습니다. 다음 섹션에서는 실제 HTTP 헤더를 다룹니다.
HTTP 응답 헤더
이 섹션에서는 Cross-Origin Resource Sharing 스펙에 의해 정의된 대로 접근 제어를 위해 서버가 응답하는 HTTP 응답 헤더들을 나열하고 있습니다. 이전 섹션에서는 이런 내용에 대한 개요들을 예를 들어 알아보았습니다.
Access-Control-Allow-Origin
반환된 리소스는 다음과 같은 문법을 가진 Access-Control-Allow-Origin
헤더를 가지고 있어야 합니다:
Access-Control-Allow-Origin: <origin> | *
origin
파라메터는 리소스에 접근하는 URI을 특정합니다. 브라우저는 이것을 반드시 강제해야 합니다. 자격 증명 없는 요청에 대해, 서버는 와일드 카드인 "*"을 특정할 수 있으며, 그로 인해 리소스에 접근하는 출처는 어떤 것이든 허용됩니다.
예를 들어, https://mozilla.com가 리소스에 접근하게 하려면, 다음과 같이 지정할 수 있습니다:
Access-Control-Allow-Origin: https://mozilla.com
서버가 "*"가 아닌 출처 호스를 지정할 경우, 클라이언트에게 서버 응답이 Origin 요청 헤더의 값과는 다르다는 것을 알려주기 위한 Vary 응답 헤더 내 Origin 을 포함해야 합니다.
Access-Control-Expose-Headers
Requires Gecko 2.0(Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)이 헤더는 브라우저가 접근할 수 있도록 해주는 서버 화이트리스트 헤더를 허용합니다. 예를 들자면:
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
이 예제에서는 브라우저에 드러나도록 X-My-Custom-Header
그리고 X-Another-Custom-Header
헤더를 허용하고 있습니다.
Access-Control-Max-Age
이 헤더는 사전 전달의 결과가 얼마나 오랫동안 캐시될 수 있는지를 가리킵니다. 사전 전달 요청의 예제는 위에서 보시기 바랍니다.
Access-Control-Max-Age: <delta-seconds>
delta-seconds
파라메터는 결과가 캐시될 수 있는 초 단위의 숫자를 가리킵니다.
Access-Control-Allow-Credentials
credentials
플래그가 true인 경우 요청에 대한 응답을 내보낼 수 있는지 없는지를 가리킵니다. 사전 전달 요청에 대한 응답의 일부로 사용된 경우, 이것은 실제 요청이 자격 증명을 사용하여 이루어질 수 있는지 없는지를 가리킵니다. 간단한 GET
요청이 사전 전달되지 않았고, 자격 증명과 함께 리소스에 대한 요청이 이루어지고, 헤더가 리소스와 함께 반환되지 않은 경우, 응답은 브라우저에 의해 무시되며 웹 컨텐츠를 반환하지 않는다는 것을 명시하시기 바랍니다.
Access-Control-Allow-Credentials: true | false
자격 증명된 요청에 대해서는 위에서 다루었습니다.
Access-Control-Allow-Methods
리소스에 접근하는 경우 허용된 메서드 혹은 메서드들을 지정합니다. 이것은 사전 전달 요청에 대한 응답에 사용됩니다. 요청이 사전 전달된 상태의 조건은 위에서 다루었습니다.
Access-Control-Allow-Methods: <method>[, <method>]*
사전 요청 예제는 위에서 보았으며, 이 헤더를 브라우저에 전송하는 예제를 포함하고 있습니다.
Access-Control-Allow-Headers
실제 요청이 이루어지는 경우 어떤 HTTP 헤더가 사용될 수 있는지를 나타내기 위해 사전 전달 요청에 대한 응답에서 사용됩니다.
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
HTTP 요청 헤더
이 섹션은 cross-origin 공유 기능을 사용하여 HTTP 요청을 호출할 때 클라이언트가 사용할 수 있는 헤더들을 나열하고 있습니다. 이 헤더들은 서버에 대한 호출이 이루어질 때 당신이 직접 설정하는 것임을 알아두시기 바랍니다. cross-site XMLHttpRequest
기능을 사용하는 개발자들은 프로그램 상으로 어떤 cross-origin 공유 요청의 헤더들도 설정해서는 안됩니다.
Origin
cross-site 접근 요청 혹은 사전 전달 요청의 출처를 가리킵니다.
Origin: <origin>
출처는 요청이 초기화된 곳에서 서버를 가리키는 URI입니다. 어떠한 경로 정보도 포함하지 않으며, 서버 이름만을 포함합니다.
origin
는 빈 문자열이 될 수 있습니다; 이것은 유용할 때가 있는데, 예를 들어, 소스가 data
URL인 경우에 그렇습니다.어떤 접근 제어 요청에서든 ORIGIN
헤더가 항상 전송된다는 것을 명시하시기 바랍니다.
Access-Control-Request-Method
실제 요청이 일어나는 경우 어떤 HTTP 메서드가 사용될 것인지 서버에 알리기 위해 사전 전달 요청 시에 사용됩니다.
Access-Control-Request-Method: <method>
이 헤더의 사용 예는 위에서 찾을 수 있습니다.
Access-Control-Request-Headers
실제 요청이 일어나는 경우 어떤 HTTP 헤더가 사용될 것인지 서버에 알리기 위해 사전 전달 요청 시에 사용됩니다.
Access-Control-Request-Headers: <field-name>[, <field-name>]*
이 헤더의 사용 예는 위에서 찾을 수 있습니다.
명세서
명세서 | 상태 | 비고 |
---|---|---|
Fetch The definition of 'CORS' in that specification. |
Living Standard | New definition; aims to supplant CORS spec. |
CORS | Recommendation | Initial definition. |
브라우저 호환성
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | 4 | 3.5 | 8 (via XDomainRequest) 10 |
12 | 4 |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | 2.1 | yes | yes | ? | 12 | 3.2 |
알아둬야 할 점
Internet Explorer 8과 9는 XDomainRequest 객체를 통해 CORS를 지원하고 있으나 전체 구현은 IE 10에서 제공되고 있습니다. Firefox 3.5가 cross-site XMLHttpRequests와 웹 폰트 지원을 도입하면서, 어떤 요청은 이후 버전까지 제한되었습니다. 구체적으로 말하자면, Firefox 7은 WebGL 텍스쳐에 대한 cross-site HTTP 요청을 도입하였으며, Firefox 9는 drawImage를 사용하여 캔버스에 드로잉된 이미지에 대한 지원을 추가했습니다.