react를 이용하여 localhost
에서 작업을 할 때 cors에 대한 오류가 나를 괴롭혔다...
간단히 말하자면 서로 다른 출처(Origin) 간에 리소스를 전달하는 방식을 제어하는 체제이며, CORS 요청이 가능하려면 서버에서 특정 헤더인 Access-Control-Allow-Origin과 함께 응답할 필요가 있다.
예를 들어 클라이언트 포트가 3000번이고 서버 포트가 8000번일 때 클라이언트에서 서버로 리소스를 요청했을 때 CORS 에러 메시지가 클라이언트 콘솔에 빨갛게 뜨고 데이터를 주지 않게 된다. 그래서 동일한 출처에서 리소스를 요청하면 된다.
공공데이터 API는 인터넷 상에서는 잘 들어가는 데 local에서만 CORS오류가 났었다... 또한 서버에서 헤더를 세팅을 해주는 방법이 가장 좋다하지만... 그럴 수 없으므로... PROXY 서버를 사용해서 우회하는 방법을 선택했다.
프록시 서버는 클라이언트가 프록시 서버 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속 할 수 있게 해주는 것을 의미한다. 쉽게 말해 브라우저와 서버 간의 통신을 도와주는 중계서버라고 생각하면 된다.
팀원 분께서 위의 링크를 이용해서 요청해야하는 URL 앞에 넣어서 프록시 서버 URL을 붙여서 요청하는 방법으로 문제를 해결하셨다.
https://cors-anywhere.herokuapp.com/https://www.chungbuk.go.kr/openapi-json/pubdata/pubMapForest.do
이렇게 붙여서 요청하면 CORS문제를 아주 간단히 해결할 수 있다.
하지만...아래 버튼을 눌러서 연결을 시켜줘야했고, 나는 모든 팀원들이 이 방법을 쓰기에는 비효율적이라고 생각했다.
http-proxy-middleware
라이브러리를 이용하면 배포하기 전 개발 단계 문제를 해결할 수 있다. 로컬에서만 막혀있다고 생각했다고... 이때까지는 그렇게 생각하고 있었다... 그리하여 이 방법도 괜찮을 것 같다고 생각했다.
yarn add http-proxy-middleware --dev
또는 npm i http-proxy-middleware -D
를 이용하여 라이브러리를 설치한다.setupProxy.js
파일을 src 폴더 내에 만든다.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.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 응답을 받아오는 것을 확인할 수 있었다...!!!
하지만 이 방법도 되었다... 안되었다를 반복했다.
사실 이 방법은 local에서 사용한 남이 만든 proxy 서버 이용하기
와 유사한 방법이다...! 자세한 방법은 이 분의 블로그를 참고하면 아주 쉽게 만들 수 있다! 로컬에서 사용했던 주소가 아니라 새롭게 proxy server를 만드는 이유는 Proxy Server를 이용하는 이용자 수가 적다면 더 빠르게 데이터를 가져올 수 있지 않을까...라는 생각으로 Proxy Server를 만들어서 배포를 해보았더니 대성공이었다...!
출처:
[TIL.10] 공공데이터open API. 리액트 로컬 작업 교차브라우저 cors 에러 해결 방법 proxy설정
나를 너무나 힘들게했던 CORS에러 해결하기
[배포] Netlify proxy 설정
package.json에 proxy 속성을 추가해서 쉽게 해결할 수 있는 방법도 있어요!