react에서 프록시 서버 여러 개 설정하기 (CRA 환경에서 나는 오류, 해결방안)
프록시를 공부하고 난 후 실습을 해보던 중 발견 한 오류와 그에 대한 해결방안을 기록해 놓으려고 한다.
프록시 서버 (Proxy server)_CORS 에러
proxy 서버가 1개 일 때 (webpack dev server에서 제공하는 proxy 기능 사용)
리엑트에서 프록시를 적용할 때는 package.json에서 "proxy"값을 설정하여 적용할 수 있다.
...
"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/3000"
}
그리고 기존의 fetch (or axios)를 통해 요청하던 부분에서 도메인 부분을 지워준다.
export async function getAllfetch() {
const response = await fetch('/params'); // "http://localhost/3000/params"
.then(() => {
...
})
}
이렇게 proxy서버가 1개 일 때는 쉽게 적용할 수 있다.
proxy server 가 2개 이상일때
하지만 적용해야 하는 proxy server가 2개 이상이라면 위와 같은 방식으로 적어서는 정상적으로 진행되지 않는다.
"proxy" : {
"/api" : {
"target" : "http://localhost:3000"
},
"/api2" : {
"target" : "http://localhost:4000"
}
}
구글링을 통해 알게 된 방식이다. 이렇게 객체 형태로 구현하면 된다고 많은 블로그에 적혀있었다. 하지만 package.json 을 수정하고 fetch 부분까지 수정한 뒤 실행을 시켜봤을 때 아래와 같은 오류가 떴다.

When specified, "proxy" in package.json must be a string.
Instead, the type of "proxy" was "object".
Either remove "proxy" from package.json, or make it a string.
package.json 에 있는 "proxy"는 문자열이여야 한다. 하지만 현재 proxy가 객체 형태로 적혀 있다.
package.json에 있는 proxy를 제거하던지, 객체를 문자열로 바꿔라
한마디로 package.json 파일의 proxy 안에는 객체형태가 들어가면 안된다는 말이다.
왜 이런 오류가 일어나냐면 해당 어플리케이션이 CRA로 만들어 졌기 때문이다.
React로 프로젝트를 시작할 때, Create-React-App(CRA)을 이용해 본 적이 있을 것이다. 다양한 개발 환경 설정을 간단하게 대신 해주는 것으로 편하게 프로젝트를 시작할 수 있다는 장점이 있다.
하지만 이렇게 CRA로 만들어진 프로젝트에서는 proxy를 이용할 때 객체 형태로 여러 개발 서버를 작성할 수 없는 것이다.
그렇다면 CRA 환경의 프로젝트에서 proxy를 이용해 여러 개발 서버를 작성해야 할 때는 어떻게 작성해야 할까?
이 상황에서 쓸 수 있는 것이 http-proxy-middleware이다.
npm install http-proxy-middleware --save
라이브러리를 설치해 준 뒤 src 파일 안에 setupProxy.js 파일을 생성한다 (파일명은 꼭 setupProxy여야 한다)
아래 처럼 두 가지 방법을 사용할 수 있는데 2개 이상이 되면 router를 사용하는 것이 훨씬 코드가 간단해진다.
const { createProxyMiddleware } = require('http-proxy-middleware');
//app.use를 두 번 실행하는 경우
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
),
app.use(
'/api2',
createProxyMiddleware({
target: 'http://localhost:4000',
changeOrigin: true,
})
);
};
//router를 이용하는 방법
module.exports = function(app) {
app.use(
['/api','/api2'],
createProxyMiddleware({
target: 'http://localhost:3080',
changeOrigin: true,
router:{
'/api2' : 'http://localhost:3070'
}
})
)};
그리고 기존의 fetch (or axios)를 통해 요청하던 부분에서 도메인 부분을 제거하면 proxy를 이용해 CORS에러를 받지 않고 응답을 받아올 수 있다.
fatch 부분은 webpack dev server 와 방식이 같다.