[ERROR] 공공데이터 API CORS 오류 : 배포 시에도 난 오류...🤯

나는야 토마토·2022년 3월 3일
8

ERROR

목록 보기
2/4
post-thumbnail

react를 이용하여 localhost에서 작업을 할 때 cors에 대한 오류가 나를 괴롭혔다...

CORS란?

간단히 말하자면 서로 다른 출처(Origin) 간에 리소스를 전달하는 방식을 제어하는 체제이며, CORS 요청이 가능하려면 서버에서 특정 헤더인 Access-Control-Allow-Origin과 함께 응답할 필요가 있다.
예를 들어 클라이언트 포트가 3000번이고 서버 포트가 8000번일 때 클라이언트에서 서버로 리소스를 요청했을 때 CORS 에러 메시지가 클라이언트 콘솔에 빨갛게 뜨고 데이터를 주지 않게 된다. 그래서 동일한 출처에서 리소스를 요청하면 된다.

공공데이터 API는 인터넷 상에서는 잘 들어가는 데 local에서만 CORS오류가 났었다... 또한 서버에서 헤더를 세팅을 해주는 방법이 가장 좋다하지만... 그럴 수 없으므로... PROXY 서버를 사용해서 우회하는 방법을 선택했다.

Proxy 서버란?

프록시 서버는 클라이언트가 프록시 서버 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속 할 수 있게 해주는 것을 의미한다. 쉽게 말해 브라우저와 서버 간의 통신을 도와주는 중계서버라고 생각하면 된다.

1. 남이 만든 proxy 서버 이용하기

https://cors-anywhere.herokuapp.com

팀원 분께서 위의 링크를 이용해서 요청해야하는 URL 앞에 넣어서 프록시 서버 URL을 붙여서 요청하는 방법으로 문제를 해결하셨다.

https://cors-anywhere.herokuapp.com/https://www.chungbuk.go.kr/openapi-json/pubdata/pubMapForest.do
이렇게 붙여서 요청하면 CORS문제를 아주 간단히 해결할 수 있다.

하지만...아래 버튼을 눌러서 연결을 시켜줘야했고, 나는 모든 팀원들이 이 방법을 쓰기에는 비효율적이라고 생각했다.

2. 클라이언트: http-proxy-middleware 사용하기

http-proxy-middleware 라이브러리를 이용하면 배포하기 전 개발 단계 문제를 해결할 수 있다. 로컬에서만 막혀있다고 생각했다고... 이때까지는 그렇게 생각하고 있었다... 그리하여 이 방법도 괜찮을 것 같다고 생각했다.

  • 1) yarn add http-proxy-middleware --dev 또는 npm i http-proxy-middleware -D를 이용하여 라이브러리를 설치한다.
  • 2) setupProxy.js파일을 src 폴더 내에 만든다.
  • 3) 그 안에 아래와 같은 코드를 작성한다.
const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function (app){
	app.use(
    	"/api",
      	createProxyMiddleware({
        	target: 'https://www.chungbuk.go.kr/openapi-json/pubdata/pubMapForest.do',
          	changeOrigin: true,
          	pathRewrite: {
            	'^/api': ''
            }
        })
    )
}

그 후에 axios 또는 fetch를 이용하여 데이터를 가져올 때 /api를 이용해야한다. 왜냐하면 셋업프록시파일에서 이 프로젝트 내에서 타겟주소를 String 변수 '/api'로 사용하겠다고 설정했기 때문이다.

import axios from 'axios';

export const getDataFromApi = async (pageNo) => {
  try {
    const res = await axios.get('/api', { params: { pageNo } });
    return JSON.parse(res.data).response.filter((_, i) => i & 1);
  } catch (error) {
    console.error(error);
  }
};

이렇게 작성해준다면 cors를 해결할 수 있다.

하지만 배포 시에 해결방법 2도 url 주소를 수정해야하였고, .env 파일도 만들어서 REACT_APP_SERVER_URL 변수를 입력해서 '/api'로 할당하게 해주었지만... 이 방법 역시 팀원들에게 .env파일을 만들어서 REACT_APP_SERVER_URL = /api를 넣어달라고 하기 까지 좋은 방법은 아니라고 생각을 했다. 그리하여 결국 팀원 분께서 하셨던 방식인 1번 해결방안이 배포 과정에도 좀 더 편리할 것 같아서 그 방법을 선택하였다.

배포 하기 위해서 https://cors-anywhere.herokuapp.com/https://www.chungbuk.go.kr/openapi-json/pubdata/pubMapForest.do 이 주소를 => https://www.chungbuk.go.kr/openapi-json/pubdata/pubMapForest.do 변경하면 잘 될 것이라고 생각했다...
하지만... netlify를 통해 배포하니 또 다시 CORS 오류가 발생하였고, 여러 블로그를 찾아보면서 문제를 해결하였다...!!!

배포: Netlify proxy 설정

netlify.toml파일을 루트 폴더에 만들어준 후, 아래와 같은 파일을 만든다.

[[redirects]]
from = "/proxy/*"
to = "https://www.chungbuk.go.kr/openapi-json/pubdata/pubMapForest.do:splat"
status = 200
force = true

그 다음 연결하는 주소를 localhost가 아닌 경우에 netlify.toml에 설정해둔 proxy값을 할당 받는다는 의미를 가진 코드이다.

const PROXY = window.location.hostname === 'localhost' ? '' : '/proxy';
export const API_URL = `${PROXY}`;

이렇게 작성해서 배포를 해준다면!! 성공적으로 API 응답을 받아오는 것을 확인할 수 있었다...!!!

하지만 이 방법도 되었다... 안되었다를 반복했다.

배포: Heroku를 이용한 Proxy Server(이걸로 해결함!!!)

사실 이 방법은 local에서 사용한 남이 만든 proxy 서버 이용하기와 유사한 방법이다...! 자세한 방법은 이 분의 블로그를 참고하면 아주 쉽게 만들 수 있다! 로컬에서 사용했던 주소가 아니라 새롭게 proxy server를 만드는 이유는 Proxy Server를 이용하는 이용자 수가 적다면 더 빠르게 데이터를 가져올 수 있지 않을까...라는 생각으로 Proxy Server를 만들어서 배포를 해보았더니 대성공이었다...!


출처:
[TIL.10] 공공데이터open API. 리액트 로컬 작업 교차브라우저 cors 에러 해결 방법 proxy설정
나를 너무나 힘들게했던 CORS에러 해결하기
[배포] Netlify proxy 설정

profile
토마토마토

4개의 댓글

comment-user-thumbnail
2022년 3월 8일

package.json에 proxy 속성을 추가해서 쉽게 해결할 수 있는 방법도 있어요!

1개의 답글
comment-user-thumbnail
2023년 1월 9일

헤로쿠 이제 유료래요 ㅠㅠ.

답글 달기
comment-user-thumbnail
2024년 1월 15일

잘 보고 갑니다 가뭄에 단비같은 게시글 :))))))

답글 달기