React 프로젝트 CORS 해결

한호수 (The Lake)·2023년 7월 17일
0
post-thumbnail
post-custom-banner

개요

스프린트 진행중 프론트와 백엔드 API 연결 테스트 중 CORS를 만나게 되었다. 백엔드 개발자분 께서 응답 헤더에 Access-Control-Allow-Origin를 추가해주었지만 프론트에서 받은 응답 헤더에는 없었고, 똑같이 CORS가 발생하여 차단되었다. 시간이 없는 관계로 프론트에서 프록시를 사용해서 우회하기로 하였다.

개발 환경

로컬에서는 번들러(Vite)에서 제공하는 server proxy 옵션을 사용하였다.

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import * as path from 'path';

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }],
  },
  server: {
    proxy: {
      // 문자열만 사용한다면 프록시를 거쳐 아래와 같이 변경된 주소로 요청된다.
      '/api': // http://localhost:5173/api -> https://www.api.com/api
        'https://www.api.com', // 백엔드 api 주소
    },
  },
});
const getImage = async (hobbyId: string): Promise<IHobbyData> => {
  const data = await (await fetch(`/api/v1/hobbies/${hobbyId}`)).json();
	// 위 요청은  http://localhost:5173/api/v1/hobbies/${hobbyId} 
    // -> https://www.api.com/api/v1/hobbies/${hobbyId} 로 요청된다.
  return data;
};

vite.config.ts 에서 제공하는 proxy 에는 다양한 옵션들이 있으며 링크를 통해 확인할 수 있다.

배포 후

배포는 Netlify를 사용하였는데, Netlify에서는 제공하는 redirects 기능을 사용하여 proxy를 제공하고 있어서 해당 기능을 사용하였다.

netlify.toml 파일을 만들어 package.json과 같은 디렉토리에 배치하였다. to 주소 끝 :splat 은 요청 시 남은 경로 및 쿼리스트링이 매칭되는 자리이다.

[[redirects]]
from = "/proxy/*"
  to = "https://www.api.com/:splat"  
  status = 200
  force = true

[[redirects]]
from = "/*"
  to = "/index"  
  status = 200
import { PROXY } from '@/constants/proxyURL';

const getImage = async (hobbyId: string): Promise<IHobbyData> => {
  const data = await (await fetch(`${PROXY}/api/v1/hobbies/${hobbyId}`)).json();
  
  return data;
};
// proxyURL.ts

// netlify에서 설정한 프록시 주소로 환경에 따라 변경될 수 있게 추가한다.
export const PROXY = window.location.hostname === 'localhost' ? '' : '/proxy';

React를 사용한 SPA로 개발하였기 때문에 배포환경에서 경로가 변경되고 새로고침이 된다면 NotFound404를 뿜어내게된다. netlify.toml 에서 규칙들은 순서를 가지며 "/proxy"를 우선시하고 매칭되는 주소가 없다면 아래 조건에 의해 index.html파일을 리턴하게 된다.

마무리

촉박한 상황에서 해당 문제를 해결하기 위해 최선의 선택은 아니었을 수 있지만 백엔드 분들과 협업하며 여러가지 배워갈 수 있었고, 프록시에 대해 공부할 수 있는 좋은 기회가 되었다. 아마 다음에 CORS 에러를 만난다고 해도 익숙하게 조치할 수 있을 것 같다.

profile
항상 근거를 찾는 사람이 되자
post-custom-banner

0개의 댓글