[React] axios 사용 시 proxy 설정 방법(CRA, Vite) - CORS관련 오류 해결하기
같은 네트워크에 프론트단과 백단 서버를 같이 운영 중이라면 한번쯤은 만날
CORS관련 오류를 해결하는 방법을 정리해 보고자 한다.
(우선 개발 서버에서만 가능하고, 배포 후에는 다른 방법을 써야하는 경우도 있다.)
프록시 설정을 위해 미들웨어를 사용하기도 하는데
오늘은 간단한 방법으로 package.json 을 수정하여 처리하는 방법을 소개해 보고자 한다.
1. Axios 란?
node.js와 브라우저를 위한 Promise 기반 HTTP클라이언트이다.
리엑트에서는 GET, POST, PUT, DELETE 등의 메소드를 지원하기 때문에 쉽게 사용이 가능하다.
주로 백엔드 서버 단으로 API를 호출할 경우에 사용하며
config를 미리 지정해 놓고 인스턴스를 생성해 재사용성을 높일 수 있다.
2. CORS 란?
CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)이다.(?)
출처가 교차한다는건 리소스를 주고 받으려는 두 출처가 다르다는 뜻이다.
axios에서 요청을 보낼때 만약
http://localhost:3000/ 의 프론트 노드 서버에서
http://localhost:8080/api 의 백엔드 자바 서버로 요청을 한다고 가정해보자.
URL에서 프로토콜(http)과, 포트(3000,8080), 도메인(localhost) 이 세가지가 출처를 구성하게 되는데
만약 이 중 하나라도 다르면 오류가 발생하게되고,
이 오류는 CORS가 가능하도록 설정해서 리소스 요청, 응답을 허용 해야 한다.
보통 백엔드 단에서 처리하나, 프론트 단에서도 처리가 가능하다.
현재 같은 로컬(같은 피씨나 같은 네트워크 구조)에서 서버를 실행하고 있어 프로토콜(http)과 도메인(localhost)는 같게 된다.
하지만 각각의 포트가 3000과 8080으로 다르기 때문에 출처가 다르다고 판단해 버리는 것이고,
따라서 CORS 를 설정한다는 건 출처가 다른 서버간의 리소스 공유를 허용 하게 된다는 의미이다.
출처가 다르더라도 리소스 호출을 허용할 출처를 명시해 이를 해결할 수 있다!
3. 프록시(Proxy) 란?
클라이언트가 프록시 서버를 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있도록 해주는 컴퓨터 시스템이나 응용 프로그램.
서버와 클라이언트 사이에 중계시스템으로 대신 통신해 주는 것을 프록시라하며, 그 기능을 프록시 서버라고 한다.
proxy 미들웨어를 이용하여 문제를 해결하기도 한다.
웹 애플리 케이션이 리소스를 직접적으로 요청하는 대신, 프록시 서버를 사용하여 웹 애플리케이션에서 리소스로 요청을 전달하는 방법이다.
웹 애플리케이션이 리소스와 동일한 출처에서 요청을 보내는 것처럼 보이므로 에러를 방지할 수 있다.
4. CRA 란?
리액트 앱을 설정할 수 있도록 하는 명령어다
명령어를 입력하면 자동으로 프로젝트 폴더를 생성해 준다.
create react app을 줄여서 cra라고 부른다.
빌드 dependency를 관리하고
웹팩, 바벨, ESLint 등 다양한 패키지를 가지고 있다.
자동으로 버전 업데이트를 지원해 준다.
npx create-react-app my-app
CRA 프로젝트에서의 프록시 설정 후 오류 해결 방법
package.json 파일에서
요청 할 서버로 프록시를 지정해 준다.
가장 마지막 부분에 "proxy" : "http://localhost:8080" 으로 작성해 주면 된다.
{
"name": "m",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.8",
"dotenv": "^16.4.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.3",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:8080"
}
만약, 다중 프록시를 적용하거나, 특정 엔드포인트만 열게 된다면
프록시를 여러개 설정할 수 도 있다.
"/"를 사용하면 전체를 설정하게 되므로 가급적 사용하지 않는것이 보안상 유리하다.
{
...
"proxy": {
"/": {
"target": "http://localhost:8080"
},
"/auth": {
"target": "http://localhost:8081"
}
}
}
이후 서버 재부팅 후,
실제 axios 호출 방법은 아래와 같이 베이스 URL을 제외한 엔드포인트로 작성해 주면 된다.
const response = await axios.get("/todos");
5. Vite 란?
Vite(비트)는 프랑스 어로 빠르다는 뜻을 가진 단어로, 리엑트 뿐만아니라 Vue.js, Svelte 등 다양한 템플릿을 지원하는 빌드 도구이다.
빠르고 간결한 모던 웹 프로젝트 개발 경험에 초점을 맞춰 실제로도 굉장히 빠른 서버로딩을 보여준다.
Node.js 18버전 이상을 지원하고 아래 명령어로 생성 가능하다.
npm create vite@latest my-app -- --template react
cra와는 다르게 'npm run dev' 명령어로 서버를 시작할 수 있다.
npm run dev
Vite 프로젝트에서의 프록시 설정 후 오류 해결 방법
vite.config.json 파일에서
프록시 경로를 설정할 수 있다.
export default defineConfig({
plugins: [react()],
server: {
proxy: {
'/api': {
target: 'https://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
secure: false,
}
}
}
})
이후 실제 사용 시 아래와 같이 줄여서 사용 가능하다.
axios.get("/api/getList")
6. 다른 해결 방법들
http-proxy-middleware
npm install http-proxy-middleware
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:8080',
changeOrigin: true,
})
);
};
참고 자료 : CORS (https://docs.tosspayments.com/resources/glossary/cors)
(https://create-react-app.dev/docs/proxying-api-requests-in-development/)