React Vite CORS Error 해결
끝말잇기 프로젝트 진행 중 무의미한 글자를 거르기 위해 국립국어원 API를 이용하게 되었다.
API에 정보가 있으면 입력이 가능하고, 없으면 입력이 되지 않는 기능 구현이 필요했기 때문이다.
하지만 url을 연결 하자마자 바로 오류가 생겼다.
리액트 Vite에서 API 연결하는 법은 하단 블로그에 포스팅 했는데, 너무 상세한 내용은 빠진듯 해 보충을 위해 더 작성하려고 한다.
https://deer-develope-diary.tistory.com/14
React Vite 프로젝트 API 호출
리액트 API 호출을 위해서는 어떤 방식으로 프로젝트를 생성했는지에 따라 호출 방법이 다르다. 현재 크게 두가지 방법으로 리액트 프로젝트를 생성할 수 있다.1. Creat-React-App(CRA)를 이용한 프로
deer-develope-diary.tistory.com
하단의 문구가 콘솔에 에러 메세지로 떴던 문구인데,
Access to XMLHttpRequest at 'https://stdict.korean.go.kr/api?~~~~~' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
처음에 CORS 에러가 무슨 에러인지 몰라 검색해보니 도시 괴담 같은 이야기만 보였다.
대충 '에러 있어~' 알려주는 느낌으로 받아지는 듯 했다.
그래도 에러 메세지가 뜰 때 얼마나 감사한가... 검색된 내용을 확인해보니 CORS에 대한 기본적인 지식이 필요해 보였다.
CORS란?
CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)를 번역하면 **“교차 출처 리소스 공유”**에요. 여기서 출처가 교차한다는 게 무슨 뜻일까요? 출처는 ‘오리진origin’의 번역 표현이에요. 우리가 흔히 알고 있는 URL에서 도메인만 뜻하는 게 아니라 프로토콜과 포트까지 포함하는 개념이죠. 출처를 구성하는 세 요소는 프로토콜·도메인(호스트 이름)·포트로, 이 중 하나라도 다르면 CORS 에러를 만나게 됩니다.
서로 다른 출처를 가진 리소스를 공유하기 위해서는 막무가내로 연결해 줘! 한다고 연결이 되는 게 아니라 상대의 출처가 명확한지, 요청 요구서가 정확하게 쓰여 있는 지를 판단하여 요청에 응하기 때문에 문제가 있으면 응답하지 않는다.
CORS 에러란?
위에 인용 된 Toss 개발자센터에 적힌 글로 읽어보니 왜 CORS 에러가 어려운 지 알 것 같았다. 세 요소 중 한 개 라도 오류가 생기면 뜨는 오류 같은데 너무 광범위 하고 명확하게 이것이 문제다! 라고 알려주는 게 없어서 더 어려운 에러인 듯 했다.
하지만 다른 메시지 보다 명확하지 않을 뿐 오류 메시지를 차분히 읽어 보면 어디서 에러가 났는 지 충분히 파악 할 수 있었다.
(그냥 꽥 하고 죽어서 흰 화면만 뜨는 자바스크립트보단 예뻤달까..ㅠㅠ)
내가 떴던 오류 메시지는 아래와 같다.
Access to XMLHttpRequest at 'https://stdict.korean.go.kr/api?~~~~~' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
직역하면 내가 요구한 api주소를 내 localhost에서 접근하려고 했으나, Access-Control-Allow-Origin(허용되는 출처 제어)이 존재하지 않아 접근할 수 없다. 라는 뜻이 된다.
CORS는 추가 Http 헤더를 사용해서 자원 접근을 통제 하는데, 요청한 url과 내 로컬 url이 달라 요청이 반려 된 것이다.
그렇다면 어떻게 CORS의 마음에 들게 접근하여 허락을 받아낼 수 있을까?
크게 두 가지 방법이 있다.
첫번째는 에러 메세지에 뜬 대로 헤더에 Access-Control-Allow-Origin의 출처를 명시하거나 모든 출처를 받게끔 변경해 준다.
하지만 보안 상의 이유로 CORS를 사용하여 요청과 접근을 통제하는데 모든 출처를 받게 되면 보안 위협이 매우 커질 수 있다.
또한 출처를 명시 하는 것은 요청 마다 header를 설정 해 줘야 하기 때문에 번거로웠다.
두번째는 proxy를 이용하여 웹이 직접적으로 요청하는 것이 아니라 프록시가 웹의 요청을 전달하는 방식으로 해결 할 수 있다.
vite.config.js 파일에 하단과 같이 프록시 서버를 설정해 줬다.
server: {
proxy: {
'/api': {
target: 'https://stdict.korean.go.kr/api',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '') // 경로 재작성
}
}
}
proxy를 통하여 경로를 재 작성 하여 요청 하면 내가 요청 했던 localhost에서 https://stdict.korean.go.kr/~~~~ 로 바뀌어 요청 된다.
그러면 요청한 url과 로컬 url이 동일해 지기 때문에 Access-Control-Allow-Origin 문제를 우회하는 것으로 해결 할 수 있다.
출처: