[React] 서비스 통합 - fetch, CORS

박이레·2022년 11월 7일
0

React

목록 보기
7/12

 마침내 여기까지 왔습니다. 서비스 통합. 백엔드 애플리케이션과 프론트엔드 애플리케이션을 통합하는 일입니다. 이걸 하고 싶었습니다.

배우고 나니 별 거 아닌 일이지만, 이걸 위해 한 달간 JS와 React에 빠져 살았습니다. 지나간 시간들이 아마득합니다.

프론트엔드에서는 fetch() 함수를 사용해서 백엔드와 연결합니다. 이때 백엔드에서는 CORS 문제가 발생됩니다. 이번 글에서는 fetch() 함수로 백엔드와 연결하고, CORS 문제를 해결하는 과정을 적습니다.

프론트엔드 애플리케이션
백엔드 애플리케이션


FrontEnd

① fetch()

프론트엔드 애플리케이션 App.js에서 fetch 함수를 사용합니다. 이후 localhost:3000에서 개발자 도구를 확인합니다. 그러면 아래 사진과 같이...!! CORS 에러를 확인할 수 있습니다!

function App() {
// 기존 코드
  const requestOptions = {
    method: "GET",
    headers: { "Content-Type": "application.json"},
  };

  fetch("http://localhost:8080/todo", requestOptions)
  .then((response) => response.json())
  .then(
    (response) => {
      setItems(response.data);
    },
    (error) => {
      
    }
  )
// 기존 코드
}

② CORS 에러 발생!

CORS. Cross-Origin Resource Sharing. 처음 리소스를 제공한 도메인(Origin)이 현재 요청하려는 도메인과 다르더라도 요청을 허락해주는 웹 보안 방침입니다. 설명이 어렵습니다. 에러 메시지를 볼까요?

Access to fetch at 'http://localhost:8080/todo' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

백엔드 서버에서 프론트 엔드 서버(Origin)로 가져오는 액세스가 CORS 정책에 의해 차단됐습니다. 요청한 리소스에 Access-Control-Allow-Origin 헤더가 없는데요. 불투명한 응답이어도 사용하시겠다면, 요청 모드를 'no-cors'로 설정해주세요. 그렇게 하면 리소스를 가져올 수 있습니다.

이해를 돕기 위해 의역했습니다.

그럼 문제를 해결하기 위해 no-cors 설정을 추가합니다. 해당 작업은 백엔드 애플리케이션에서 진행합니다.

BackEnd

③ no-cors 설정

WebMvcConfigurer를 상속해 addCorsMappings 메서드를 오버라이드 합니다. 설정을 마치고 백엔드 애플리케이션을 재구동합니다. 그러면 아래 사진과 같이...!! CORS 에러가 사라진 것을 확인할 수 있습니다!

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    private final long MAX_AGE_SECS = 3600;

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 모든 경로에 대해
        registry.addMapping("/**")
                // Origin이 http:localhost:3000에 대해
                .allowedOrigins("http://localhost:3000")
                // GET, POST, PUT, PATCH, DELETE, OPTIONS 메서드를 허용합니다.
                .allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(MAX_AGE_SECS);
    }
}

그런데.. Network 탭을 살펴보면..

계속해서 todo가 끝없이 나열됩니다.. 프론트엔드 애플리케이션이 무한 루프에 빠졌습니다.
무한 루프를 해결하기 위해서는 React의 Effect Hook, ECMA Script의 Promise, fetch() API에 대해 알아야 합니다.



다음 글은 백엔드와 프론트엔드를 통합하는 방법 - Effect Hook, Promise에 대해 다룹니다.

💁‍♂️reference

React.js, 스프링 부트, AWS로 배우는 웹 개발 101

김다정 지음ㅣ에이콘출판ㅣ2022ㅣ도서 정보


EOD.

profile
혜화동 사는 Architect

0개의 댓글