이를 통해 브라우저는 XMLHttpRequest 요청을 교차-오리핀 서버에 발행하여 AJAX가 동일한 원점에서만 사용할 수 있다는 제한을 극복 할 수 있습니다.
이 기사는 CORS의 내부 메커니즘을 자세히 소개합니다.
(사진 설명 : UAE, Al Ain의 Oasis Park에서 촬영)
1. 소개
CORS에는 브라우저와 서버 지원이 모두 필요합니다. 현재 모든 브라우저는이 기능을 지원하며 IE 브라우저는 IE10보다 낮을 수 없습니다.
전체 CORS 커뮤니케이션 프로세스는 브라우저에서 자동으로 완료되며 사용자 참여가 필요하지 않습니다. 개발자의 경우 CORS 커뮤니케이션은 동일한 원산지 Ajax 커뮤니케이션과 다르지 않으며 코드는 정확히 동일합니다. 브라우저에서 AJAX가 크로스 오리핀을 요청한다는 것을 알게되면 추가 헤더 정보를 자동으로 추가하고 때로는 추가 요청이 있지만 사용자는 느끼지 않습니다.
따라서 CORS 통신 구현의 핵심은 서버입니다. 서버가 CORS 인터페이스를 구현하는 한, 교차 오리핀 통신을 수행 할 수 있습니다.
두 가지 요청
브라우저는 CORS 요청을 간단한 요청과 단순하지 않은 요청의 두 가지 범주로 나눕니다.
다음 두 가지 주요 조건이 동시에 충족되는 한 간단한 요청입니다.
(1) 요청 방법은 다음 세 가지 방법 중 하나입니다.
HeadgetPost
(2) HTTP의 헤더 정보는 다음 필드를 초과하지 않습니다.
acceptaccept-languagecontent text/plain languagelast-event-idcontent-type : 3 값으로 제한 multipart/form-data 있습니다 application/x-www-form-urlencoded
동시에 위의 두 조건을 충족하지 않는 사람은 단순한 요청입니다.
이 두 요청에 대한 브라우저의 처리는 다릅니다.
3. 간단한 요청 3.1 기본 프로세스
간단한 요청의 경우 브라우저는 CORS 요청을 직접 발행합니다. 구체적으로 헤더 정보에 Origin 필드를 추가하십시오.
다음은 예입니다. 브라우저는이 크로스 오리핀 Ajax 요청이 간단한 요청이라는 것을 발견했으며 헤더 정보에 Origin 필드를 자동으로 추가했습니다.
GET /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
위의 헤더 정보에서 Origin 필드는 요청이 발생하는 소스 (프로토콜 + 도메인 이름 + 포트)를 나타내는 데 사용됩니다. 이 값에 따라 서버는 요청에 동의할지 여부를 결정합니다.
Origin 에 의해 지정된 소스가 권한 범위 내에 있지 않으면 서버는 일반 HTTP 응답을 반환합니다. 브라우저는이 응답의 헤더 정보에 Access-Control-Allow-Origin 필드가 포함되어 있지 않다는 것을 발견 했으므로 (자세한 내용은 아래 참조) 오류가 발생하여 오류가 발생하여 XMLHttpRequest 의 onerror 콜백 함수에 의해 캡처 된 것으로 알려져 있습니다. HTTP 응답의 상태 코드는 200 일 수 있으므로이 오류는 상태 코드로 식별 할 수 없습니다.
Origin 에 의해 지정된 도메인 이름이 권한 범위 내에 있으면 서버에서 반환 한 응답에는 여러 헤더 필드가 있습니다.
Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Credentials: trueAccess-Control-Expose-Headers: FooBarContent-Type: text/html; charset=utf-8
위의 헤더 정보 중에는 CORS 요청과 관련된 세 가지 필드가 있으며 모두 Access-Control- 로 시작합니다.
(1) 액세스-제어-홀로-오리진
이 필드가 필요합니다. 그 값은 요청 시점의 Origin 필드의 값 또는 A * 로서 도메인 이름에 대한 요청이 수락되었음을 나타냅니다.
(2) 액세스-제어 홀로 인증
이 필드는 선택 사항입니다. 그 가치는 쿠키를 전송할지 여부를 나타내는 부울 값입니다. 기본적으로 쿠키는 CORS 요청에 포함되지 않습니다. true 로 설정하여 서버가 명시 적으로 허용 함을 의미합니다. 쿠키는 요청에 포함되어 서버로 함께 보낼 수 있습니다. 이 값은 true 로만 설정할 수 있습니다. 서버가 브라우저로 쿠키를 보내지 않으면 필드를 삭제하십시오.
(3) 액세스 제어 노출 헤더
이 필드는 선택 사항입니다. CORS가 요청되면 XMLHttpRequest 객체의 getResponseHeader() 메소드는 6 개의 기본 필드 만 얻을 수 있습니다 : Cache-Control , Content-Language , Content-Type , Expires , Last-Modified , Pragma . 다른 필드를 얻으려면 Access-Control-Expose-Headers 로 지정해야합니다. 위의 예는 getResponseHeader('FooBar') FooBar 필드의 값을 반환 할 수 있음을 지정합니다.
3.2 점수가있는 속성
위에서 언급했듯이 CORS 요청은 기본적으로 쿠키 및 HTTP 인증 정보를 보내지 않습니다. 쿠키를 서버로 보내려면 한편으로는 서버가 Access-Control-Allow-Credentials 필드에 동의하고 지정해야합니다.
Access-Control-Allow-Credentials: true 반면에 개발자는 AJAX 요청에서 withCredentials 속성을 열어야합니다.
var xhr = new XMLHttpRequest();xhr.withCredentials = true;그렇지 않으면 서버가 쿠키를 보내는 데 동의하더라도 브라우저는 전송되지 않습니다. 또는 서버는 쿠키를 설정해야하며 브라우저는 쿠키를 처리하지 않습니다.
그러나 withCredentials 설정이 생략되면 일부 브라우저는 여전히 쿠키를 함께 전송합니다. 이 시점에서, 당신은 명백하게 withCredentials 닫을 수 있습니다.
xhr.withCredentials = false; 쿠키를 보내려면 Access-Control-Allow-Origin 별표로 설정할 수 없으며 요청 된 웹 페이지와 일치하는 명시 적 도메인 이름을 지정해야합니다. 동시에, 쿠키는 여전히 동일한 원래 정책을 따릅니다. 서버 도메인 이름이있는 쿠키 만 업로드됩니다. 다른 도메인 이름의 쿠키는 업로드되지 않으며, Original (Cross-Original) 웹 페이지 코드의 document.cookie 는 서버 도메인 이름에서 쿠키를 읽을 수 없습니다.
4. 비소 요청 4.1 비행 전 요청
비 단순 요청은 요청 방법을 PUT DELETE 것과 같이 서버 Content-Type 대한 특별한 요구 사항이있는 요청 application/json .
간단한 요청이 아닌 CORS 요청은 공식 커뮤니케이션 전에 "프리 플라이트"요청이라고하는 HTTP 쿼리 요청을 추가합니다.
브라우저는 먼저 서버에 현재 웹 페이지가 위치한 도메인 이름이 서버의 라이센스 목록에 있는지, HTTP 동사 및 헤더 필드를 사용할 수 있는지 여부를 묻습니다. 긍정적 인 응답이 접수 된 경우에만 브라우저는 공식 XMLHttpRequest 요청을 발행합니다. 그렇지 않으면 오류 가보고됩니다.
아래는 브라우저 JavaScript 스크립트입니다.
var url = 'http://api.alice.com/cors';var xhr = new XMLHttpRequest();xhr.open('PUT', url, true);xhr.setRequestHeader('X-Custom-Header', 'value');xhr.send();
위의 코드에서 HTTP 요청 방법이 PUT 사용자 정의 헤더 정보 X-Custom-Header 보냅니다.
브라우저는 이것이 단순하지 않은 요청이라는 것을 발견하므로 자동으로 "사전 비행"요청을 발행하여 서버가 요청할 수 있는지 확인해야합니다. 아래는이 "프리 플라이트"요청에 대한 HTTP 헤더 정보입니다.
OPTIONS /cors HTTP/1.1Origin: http://api.bob.comAccess-Control-Request-Method: PUTAccess-Control-Request-Headers: X-Custom-HeaderHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0... "Preflight"요청에 사용 된 요청 방법은 OPTIONS 이며,이 요청이 문의하는 데 사용됨을 나타냅니다. 헤더 정보에서 키 필드는 Origin 이며 요청이 어떤 소스에서 나오는지를 나타냅니다.
Origin 필드 외에도 "Preflight"요청의 헤더 정보에는 두 개의 특수 필드가 포함됩니다.
(1) 액세스 제어-반복-방법
이 필드는 브라우저의 CORS 요청에 사용할 HTTP 방법을 나열해야합니다. 위의 예는 PUT .
(2) 액세스 제어-반복 헤더
이 필드는 브라우저 CORS 요청이 보낼 추가 헤더 정보 필드를 지정하는 쉼표로 구분 된 문자열입니다. 위의 예는 X-Custom-Header 입니다.
4.2 비행 전 요청에 대한 응답
서버가 "프리 플라이트"요청을받은 후, Origin , Access-Control-Request-Method 및 Access-Control-Request-Headers 필드를 확인한 후 크로스 오리핀 요청이 허용되는지 확인하고 응답 할 수 있습니다.
HTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:15:39 GMTServer: Apache/2.0.61 (Unix)Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderContent-Type: text/html; charset=utf-8Content-Encoding: gzipContent-Length: 0Keep-Alive: timeout=2, max=100Connection: Keep-AliveContent-Type: text/plain
위의 HTTP 응답에서 키는 Access-Control-Allow-Origin 필드입니다. 이는 http://api.bob.com 이 데이터를 요청할 수 있음을 의미합니다. 이 필드는 또한 크로스 오리핀 요청에 동의하기 위해 별표로 설정할 수 있습니다.
Access-Control-Allow-Origin: *
브라우저가 "프리 플라이트"요청을 무효화하면 일반 HTTP 응답이 반환되지만 CORS 관련 헤더 필드는 없습니다. 현재 브라우저는 서버가 프리 플라이트 요청에 동의하지 않기 때문에 XMLHttpRequest 객체의 onerror 콜백 함수에 의해 오류가 트리거되고 캡처됩니다. 콘솔은 다음 오류 메시지를 인쇄합니다.
XMLHttpRequest cannot load http://api.alice.com.Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
서버가 응답하는 다른 CORS 관련 필드는 다음과 같습니다.
Access-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000(1) 액세스-제어 획기 방법
이 필드가 필요하며 그 값은 서버에서 지원하는 모든 크로스 도메인 요청 방법을 나타내는 쉼표로 구분 된 문자열입니다. 모든 지원되는 방법은 브라우저가 요청한 방법뿐만 아니라 반환됩니다. 이것은 여러 "프리 라이트"요청을 피하는 것입니다.
(2) 액세스-제어 홀로 헤더
브라우저 요청에 Access-Control-Request-Headers 필드가 포함 된 경우 Access-Control-Allow-Headers 필드가 필요합니다. 또한 서버에서 지원하는 모든 헤더 필드가 "Preflight"의 브라우저에서 요청한 필드에만 국한되지 않음을 나타내는 쉼표로 구분 된 문자열입니다.
(3) 액세스-제어 홀로 인증
이 필드는 간단한 방식으로 요청했을 때와 같은 의미를 갖습니다.
(4) 액세스 제어-대법원
이 필드는 선택 사항 이며이 프리 플라이트 요청의 유효 기간을 몇 초 만에 지정하는 데 사용됩니다. 위의 결과에서, 유효 기간은 20 일 (1728,000 초)이며, 이는 응답이 1728,000 초 (즉, 20 일) 동안 캐시됨을 의미합니다. 이 기간 동안 다른 프리 플라이트 요청은 필요하지 않습니다.
4.3 브라우저의 일반 요청 및 응답
서버가 "프리 라이트"요청을 전달하면 브라우저의 일반 CORS 요청이 간단한 요청과 동일 할 때마다 Origin 헤더 정보 필드가 있습니다. 서버의 응답에는 Access-Control-Allow-Origin 핀 헤더 필드도 있습니다.
아래는 "프리 플라이트"요청 후 브라우저의 일반적인 CORS 요청입니다.
PUT /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comX-Custom-Header: valueAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
위 헤더 정보의 Origin 필드는 브라우저에서 자동으로 추가됩니다.
아래는 서버의 일반적인 응답입니다.
Access-Control-Allow-Origin: http://api.bob.comContent-Type: text/html; charset=utf-8
위의 헤더 정보에서 Access-Control-Allow-Origin 필드는 각 응답에 포함되어야합니다.
5. JSONP와의 비교
Cors는 JSONP와 같은 목적으로 사용되지만 JSONP보다 강력합니다.
JSONP는 GET 요청을 지원하며 CORS는 모든 유형의 HTTP 요청을 지원합니다. JSONP의 장점은 구식 브라우저를 지원하고 CORS를 지원하지 않는 웹 사이트에서 데이터를 요청할 수 있다는 것입니다.
(위에)