@font-face
)CORS 동작 방식에는 세 가지의 시나리오가 있다
const headers = new Headers({
'Content-Type': 'text/xml',
});
fetch('https://github.com/ooooorobo', { headers });
응답이 유효하지 않다고 판단하면 CORS 에러가 발생한다.
개발자 도구 콘솔 탭과 네트워크 탭에서 CORS error 메시지를 볼 수 있다.
Access-Control-Request-*
형태 헤더Access-Control-Request-Method
: 본 요청에서 사용할 메소드Access-Control-Request-Headers
: 본 요청에서 전송할 헤더 종류클라 ⇒ 서버: 본 요청을 보내려는 URI에 Option 메소드(Preflight) 요청을 보낸다.
// 본 요청
const headers = new Headers({
'Content-Type': 'text/xml',
});
fetch('https://roborobo.tistory.com', { headers });
...
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: GET
Connection: keep-alive
Host: roborobo.tistory.com
Origin: https://www.naver.com
Referer: https://www.naver.com/
...
서버 ⇒ 클라: 서버의 CORS 정책에 따라 Preflight에 대해 메소드, 헤더, 쿠키 등의 허용 여부에 대해 응답
Access-Control-Allow-Origin: https://roborobo.tistory.com
Content-Encoding: gzip
Content-Length: 5060
Content-Type: text/html; charset=utf-8
Date: Thu, 28 Oct 2021 05:08:23 GMT
P3P: CP='ALL DSP COR MON LAW OUR LEG DEL'
Vary: Accept-Encoding
X-UA-Compatible: IE=Edge
Access-Control-Allow-Origin
값 등을 보낸다.GET, HEAD, POST
중 하나Accept
, Accept-Language
, Content-Language
, Content-Type
, DPR
, Downlink
, Save-Data
, Viewport-Width
, Width
를 제외한 헤더를 사용하면 안된다.Content-Type
를 사용하는 경우에는 application/x-www-form-urlencoded
, multipart/form-data
, text/plain
만 허용된다.credentials
옵션XMLHttpRequest
, fetch API
는 브라우저 쿠키 정보나 인증 관련 헤더를 요청에 담지 않는다.same-origin
(default): 같은 출처 간 요청만 인증 정보를 담음include
: 모든 요청에 인증 정보를 담음omit
: 모든 요청에 인증 정보를 담지 않음credentials: include
사용 시에는 브라우저가 조건을 추가로 검사한다.include
모드에서는 요청의 Access-Control-Allow-Origin
헤더에 *
를 사용할 수 없고, 명시적 URL이어야 한다.Access-Control-Allow-Credentials: true
가 있어야 한다.동일 출처 사용하기
서버에서 Access-Control-Allow-Origin 세팅
*
사용하기 ⇒ 보안 위험프록시 서버 사용
http://localhost:3000
과 같은 주소를 사용하게 되는데, 서버에서 이와 같은 범용 주소를 Access-Control-Allow-Origin
에 잘 넣어주지 않음module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://domain.com',
changeOrigin: true,
pathRewrite: { '^/api': '' },
},
}
}
}
// 혹은 package.json에서
{
...
"proxy" : "https://api.domain.com"
...
}