junior developer :)/React

react에서 프록시 서버 여러 개 설정하기 (CRA 환경에서 나는 오류, 해결방안)

ㅁ윤슬ㅁ 2022. 12. 9. 10:09
728x90
반응형

프록시를 공부하고 난 후 실습을 해보던 중 발견 한 오류와 그에 대한 해결방안을 기록해 놓으려고 한다.
프록시 서버 (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 와 방식이 같다.

728x90
반응형