[CORS] CORS란? (로컬 통신간의 CORS 에러와 해결)
1. CORS, Cross-Origin Resource Sharing 이란?
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)란, 사이트 A가 사이트 B에서 콘텐츠를 가져오려고 하면 사이트 B는 추가 HTTP 응답 헤더를 보내 이 페이지의 콘텐츠에 특정 출처에서 액세스할 수 있음이 확인되어야 한다.
[발생순서]
1. 사이트 A가 사이트 B에서 페이지를 요청하면 브라우저는 실제로 네트워크 수준에서 요청된 페이지를 가져오고,
2. 응답 헤더에 사이트 A가 허용된 요청자 도메인으로 나열되는지 확인.
3. 사이트 A는 이 페이지(사이트 B)에 액세스할 수 있음을 확인받지 못한다면,
4. 브라우저는 JavaScript 코드에 대한 응답 데이터를 거부하게되고 결국 CORS 오류가 발생한다.
[예시]
https://domain-a.com 의 프론트엔드 JavaScript 코드가 XMLHttpRequest를 사용해 https://domain-b.com/data.json을 요청하는 경우.
2. 로컬 통신간의 어처구니 없는 CORS 에러
내 컴퓨터 동일한 경로에 위치한 아래 두 파일
ajax.html에서 jsondata2.json 파일을 열려고 했다.
ajax.html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="manifest" href="/app.webmanifest" crossOrigin="use-credentials" />
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<button type="json1" id="json">읽기</button>
<div id="content">출력 영역</div>
</body>
</html>
<script>
window.addEventListener("load", (e) => {
let json1 = document.getElementById("json");
let contents = document.getElementById("contents");
json1.addEventListener("click", (e) => {
let request = new XMLHttpRequest();
request.open('GET', 'jsondata.json');
request.send('');
request.addEventListener("load", () => {
let result = JSON.parse(request.responseText);
let documents = result.documents;
for(doc of documents){
content.innerHTML += "<p>이름: "+ doc.name + "</p>";
}
});
request.addEventListener("error", () => {
alert(request.status);
});
})
})
</script>
jsondata2.json
{
"count":3,
"documents":[
{"name":"덴지", "buddy":"포치타"},
{"name":"마키마", "buddy":"냐코"},
{"name":"민지", "buddy":"JAVA"}
]
}
서버에 올린게 아니라, 간단하게 로컬에서 파일 실행을 통해 확인하려고 했는데
계속 CORS 에러가 뜨는 것이다..
Access to XMLHttpRequest at 'file:///Users/jsondata2.json' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome, https, chrome-untrusted.
해결은 VSCode의 라이브서버를 띄워, 요청 URL이
file:///[경로]/ajax.html 가 아니라 http://127.0.0.1:3000/ajax.html 가 되게 하여 해결했다.
네트워크 탭에서도 file:///[경로]/ajax.html 로 요청을 해서 왜 에러가 나는지 더 헷갈렸던..ㅠㅠ
생각해보면 자바스크립트는 클라이언트에서 동작되는거고..
예를들어 어떤 유저가 한 사이트에 들어갔을때, 누군가의 악성 코드로 그 접속한 사람 C 드라이브가 다 날아가는 코드가 실행되면 안되니까.. 자바스크립트가 컴퓨터 파일 내부?까지 알 수 없는 뭔가가 있나보다. 프론트엔드 지식이 얄팍해서 정확하게는 모르겠다..🥺
3. 동일 출처 정책(Same Origin Policy, SOP)
CORS의 반대 개념으로, 보안상의 이유로 브라우저는 스크립트 내에서 시작된 원본 간 HTTP 요청을 제한한다.
따라서 웹 응용 프로그램을 사용하거나 자체 도메인에만 HTTP 요청을 할 수 있다.
CORS 참고: https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
AJAX 참고: https://www.nextree.co.kr/p9521/