[React] ⛔ Vercel로 React 배포 후 Proxy 오류, API Response 가 html로 찍히는 Error (~ing)

Ogu·2024년 1월 25일
4

SpringBoot 서버도 삽질을 하며 서버 배포를 성공했고, 프론트분의 react 로컬에서 API 연동에서부터 CORS 오류가 뜬 이후, 스프링에서 CORS 설정을 해줬더니 값도 잘 불러왔습니다.
하지만 react를 vercel 에 배포하니 또 값을 제대로 못 받아오고 있었습니다.

분명 스프링에서도 WebMVCConfig 로 모든 Origin을 허용하고 각종 설정을 했는데 왜 안되지? vercel은 https로 배포되어서 그런가? 하지만 앞에 프로토콜도 Origin에 포함되는 것이라 상관 없을텐데?
하면서 혹시나 서버 주소에도 SSL인증을 해서 https를 붙여주었습니다.

하지만 역시 react 배포환경에서 불러오는데 실패했습니다.

먼저 앞선 상황부터 살펴보겠습니다.

문제 인식

로컬에서는 잘 작동되는 API 요청

로컬에서는 아래와 같이 API 요청하고 response를 받아와서 뿌려지고 있는데요.

실제 Response JSON 값도 잘 받아와지고있습니다.

vercel 로 react 배포 후 오류

근데 기가 막히게도 vercel로 배포만 하면 먹통이었는데요

response를 보니 이상한 html만 찍혀있는 것 아니겠씁니까..

preview도 이상한 javascript에 관해 오류가 떴습니다.

You need to enable JavaScript to run this app. 으로 구글링을 해서 캐시를 지워보고, 브라우저에서 javascript 보는걸 허용하고 등등을 해도 소용이 없더군요.

친구랑 정말 둘이 울상이어서 백엔드 담당인 저도 프론트를 하나도 몰랐는데 이것저것 검색을 시작했는데요,

분명 CORS 오류때문에 package.json에서 proxy를 설정해주었어서, local에서는 이게 작동이 됐었습니다.

하지만 빌드만 하면 무용지물이 되는 것 같았습니다.
정말 이것저것 다 구글링하고, JavaScript 어쩌구도 안되고..

그러다 혜성과 같은 저희와 상황이 완전 같은 분의 포스팅을 접했습니다.

이분의 포스팅을 보고 아 접근 자체가 완전히 틀렸던걸 깨달았죠.
그리고 개념의 중요성,, 정말 뭘 써도 알고 써야한다는 걸 뼈저리게 깨달았습니다.
그래서 Proxy에 대해 공부가 필요해졌습니다.

Proxy

그래서 Proxy가 뭔데?

proxy는 중간에 요청을 가로채서 어디에 요청을 보낼건지 origin을 설정하는 것입니다!

즉, CORS를 우회하여 (사기쳐서) 준수하기 위해 설정하는 것이죠.

우리는 힌트를 얻었다!

아니 그러면 react의 package.json 에서 proxy를 설정해줄 필요가 없잖아?

다시 아래와 같이 proxy 설정도 다시 없애주고

요청할 서버의 url을 const 변수로 만들어 주었으며,

proxy를 쓰지 않고 pure한 url에 요청을 보내도록 다시 바꿔줬습니다.

local에서 확인해봤습니다. 역시나! 잘 받아와지고있습니다!

기억을 돌이켜보니.. cors오류가 나서 proxy 설정을 했는데, spring에서 cors 설정한 버전을 늦게 배포했거나 얼레벌레 타이밍이 안맞았었는지 암튼.. 개념도 없다보니까 proxy도 그대로 두고 꼬였나보다

그러면 왜 배포하면 proxy설정한 값으로 들어가지 않고 자기 폴더 내에서 찾는 구조로 되어서 (즉 백엔드 서버로 요청을 보내지 않고)html을 반환해버리는 것이었을까요,,?

힌트를 얻고 GPT에게 물어보았습니다..


vercel에서 proxy는 따로 설정!

그렇게 새로운 실마리를 찾고 vercel proxy 설정 키워드로 구글링해본 결과, vercel에 proxy를 따로 설정해줘야 하는 것이었습니다,, 하하!

로컬(개발 환경)에서는 프록시 설정으로 CORS 문제를 우회할 수 있지만, 실제 배포 환경에서는 프록시 설정이 무시됩니다.

따라서 vercel.json 파일을 루트 디렉토리에 생성한 후 프록시 설정을 해주어야 합니다.

저희는 이미 백엔드 서버에서 Origin 을 *로 풀어주어서 따로 설정이 필요 없었지만,
서버에서 제한을 두고 있고 프론트에서 프록시로 우회해서 해야한다는 상황이라고 가정하고, vercel proxy 설정을 해보겠습니다.

Vercel에서 제공하고 있는 proxy 설정 공식 문서는 아래 링크를 참고하세요!

// vercel.json:

{
  "rewrites": [
    {
      "source": "/api/:path*",
      "destination": "https://ogu50-be.shop:path*"
    },
    {
      "source": "/api/:path*/",
      "destination": "https://ogu50-be.shop/:path*/"
    }
  ]
}

예를 들어, 클라이언트에서 요청하는 주소가 /api/로 시작한다면 proxy 서버가 https://ogu50-be.shop/로 변환 해준다는 뜻입니다

여기서 :path*는 Vercel의 동적 라우팅 문법이라고 합니다. 특정 패턴을 캡처하여 동적인 값으로 사용하는 것을 의미합니다.

GPT가 보내준 코드와의 차이점 ($q vs :path*)

// vercel.json
{
  "rewrites": [
    { "source": "/api/(.*)", "destination": "http://your-backend-server/$1" },
    { "source": "/(.*)", "destination": "/$1" }
  ]
}


해결

그럼 우리도 한번 위의 내용을 토대로 vercel.json을 작성해보도록 하겠습니다.

vercel.json

저희의 상황에 맞게 vercel.json을 작성해보겠습니다.

{
   "rewrites": [
     {
       "source": "/api/:path*",
       "destination": "https://eb-umust.umust302.shop/api/:path*"
     }
   ]
 }

main.js도 원래대로 롤백

그렇다면 앞에 잠깐 테스트해보기 위해서 붙였던 baseUrl도 다시 떼줘야겠죠?

수정한 vercel.jsonmain.js대로라면 axios로 요청이 /api/ 로 들어왔을 때, 해당 /api/ 부분을 proxy에서 설정한 주소로 바꿔주는겁니다!

따라서 다시 vercel 배포 후 확인을 해보면!!!

와 드디어 정상적으로 요청되어 불러와지는상황입니다.

여기서 눈여겨 보아야 할 것은 Request의 URL의 Origin이 서버 URL로 뜨지 않고 프론트 배포 주소 그대로 뜬다는 것입니다.
왜냐하면 중간에 Proxy가 가로 채서 Origin을 바꿔주는 것이기 때문에 원래의 Request 주소는 그대로인 셈이죠.

이거때문에 힌트를 얻기도 했었지만 사실 변동되지 않는게 맞는거였어서 참 재밌는 상황이었습니다.

그렇다면 Proxy를 왜쓸까..?

그렇다면 왜 Proxy를 쓸까요??

그건 바로 서버 요청 url을 숨기기 위해서입니다. 노출이 되면 안되기 때문에 쓰는거죠.

결론

즉, CORS 정책을 준수하는 방법은 2중 택입니다.

  1. 📟 서버에서 Access-Control-Allow-Origin 헤더를 직접 설정해주거나,
  2. 🎨 프론트에서 Proxy를 이용해서 우회 요청

따라서, 저희는 바보같이 📟을 해놓고도
🎨를 package.json으로 설정했으니 로컬(개발환경)에서는 적용이 되어 proxy 설정한 도메인으로 요청을 우회하여 보내서 받아오는데 문제가 없었지만,
vercel로 배포하니 당연히 package.json이 적용이 안됐던,,

여러가지로 전부 처음부터 접근을 잘못했던 상황이었습니다^^

저희와 같은 삽질을 하셨던 분들께 큰 도움이 돼셨길 바라면서

남은 얼레벌레 인턴 개발도 화이팅이다 내 프론트 친구야!!

참고

vercel proxy 설정

제가 이해할 때 가장 도움이 된 순서대로 입니다!

profile
私はゲームと日本が好きなBackend Developer志望生のOguです🐤🐤

2개의 댓글

comment-user-thumbnail
2024년 1월 25일

제발 회사에서 이 오류가 고쳐졌음 좋겠네요 ㅠㅠ 고생하십니다!!!

1개의 답글