[React] 서버와 통신해보자! (feat.axios)

Yeojin Choi·2021년 11월 10일
2

React 로 구성한 클라이언트 환경에서, 서버와의 통신을 통해 데이터를 받아오기 위해서 fetch 또는 axios 를 사용합니다.

이 글은 각 방법에 대해 알아보고 제 프로젝트에 적용시킨 과정을 정리한 글입니다.

1. axios? fetch?

1) Fetch API

fetch(url)
  .then((res) => 
    // handle response
  )
  .catch((error) => {
    // handle error
  })
  
//with options
fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
});
  .then((response) => response.json())
  .catch((error) => console.log(error))
  • ES6 이상의 자바스트립트에 내장된 API
  • 첫번째 인수 : url
  • 두번째 인수 : 옵션, 옵션 전달하지 않으면 요청은 항상 GET. GET 이외의 메서드나 헤더를 전달

2) axios?

Node.js와 브라우저를 위한 Promise 기반 HTTP 비동기 통신 라이브러리

  • 비동기로 HTTP 통신을 가능하게 해주고, promise 객체로 return해주기 때문에 response 데이터를 다루기도 쉽습니다.

react를 사용 시 fetch 보다 axios 를 많이 사용하는 이유?

2. Axios 설치 및 사용

  1. 설치 : npm install -D axios
  2. 환경 변수 설정 : 로컬 서버의 3000번 포트에 접속하기 위한 host url 을 환경 변수로 관리해보겠습니다. 이때 CRA 로 만든 react app 이라면 접두사로 반드시 REACT_APP_ 을 붙여줘야합니다. 그리고 환경 변수를 관리하고자 하는 파일은 반드시 root 폴더에 넣어야 합니다.
// /.env
REACT_APP_API_HOST = http://localhost:3000/

// src/constant.js
export const API_HOST = process.env.REACT_APP_API_HOST;
export const FetchStatus = {
  Request: 'Request',
  Sucess: 'Success',
  Fail: 'Fail',
};
  1. API
// src/util/api.ts
//집가서 복붙해야댐..

[ISSUE] React 에서 환경 변수 사용하기

원인

CRA 로 만든 React App 에서 환경 변수를 사용하기 위해서는 /src/.env 파일에 REACT_APP_ 로 시작하는 환경 변수를 선언해주기만 하면 됐다.

내가 진행하는 프로젝트에서는 CRA 로 만들었지만 webpack을 공부하면서 직접 설정한 configuration 파일로 동작하고 있었기 때문에 이를 인식하지 못했던 것이었다.

이런 경우 직접 Webpack 을 구성한 경우에 해당하기 때문에
1. Webpack 의 DefinePlugin 또는 EnvironmentPlugin 을 사용해 process.env 라는 전역 변수를 정의해주어야 한다. DefinePlugin은 모든 자바스크립트 코드에서 접근이 가능한 전역 변수를 선언하기 위해서 사용되는 플러그인이다. EnvironmentPlugin 은 DefinePlugin의 좀 더 간편한 버전이다.
2. dotenv 또는 dotenv-webpack 패키지를 사용해서 .env 파일에 선언한 변수를 process.env 에 로드해주어야 한다.

이때 환경 변수는 REACTAPP 으로 시작하지 않아도 된다.
CRA 프로젝트에서는 dotenv 패키지가 내장되어있기 때문에 Webpack 을 직접 구성한 경우와 달리 추가적인 설정이 필요없었던 것이다..!

해결 방법

//webpack.common.conf.js

const webpack = require('webpack');
const dotenv = require('dotenv');
dotenv.config();

// ...중략...

  plugins: [
    new webpack.DefinePlugin({
      'process.env': JSON.stringify(process.env), //.env 파일이 파싱된 객체가 process.env 에 셋팅된다.
    }),
  ],

[ISSUE] CORS

원인

CORS 는 도메인 및 프로토콜, 포트가 다른 서버의 자원을 요청하면 발생하는 이슈이다.
client : localhost:9000, server : localhost:3000 로 분리하여 개발하고 있기 때문에 포트가 달라져서 CORS 가 발생한 것 같다.

해결 방법

1. cors middleware 사용

npm install --save cors npm i --save-dev @types/cors 를 통해 패키지를 설치했다.

예시를 보면

// example
const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors()); 

이렇게 해놨길래 우리 서버측 코드에서

// Server.ts

class Server {
  // app 타입 지정
  public app: express.Application;

  // 생성자
  constructor() {
    this.app = express();
    this.app.use(cors()); //모든 cross-origin 요청에 대해 응답

    this.app.get('/', function (req, res) {
      res.send('Hello 스터D');
    });
  }
}

const server = new Server().app;

server.set('port', 3000);
server.use(express.urlencoded({ extended: true }));

했는데 안된다..?

2.Access-Control-Allow-Origin response Header 추가

// example
app.use((req, res) => {
	res.header("Access-Control-Allow-Origin", "*"); // 모든 도메인
   	res.header("Access-Control-Allow-Origin", "url"); // 특정 도메인 
});

오 이렇게 하면 되는군! 하고 우리 서버측 코드에다가

// Server.ts

class Server {
  // app 타입 지정
  public app: express.Application;

  // 생성자
  constructor() {
    this.app = express();
    
    this.app.use((req, res) => {
	res.header("Access-Control-Allow-Origin", "*"); // 모든 도메인
    });

    this.app.get('/', function (req, res) {
      res.send('Hello 스터D');
    });
  }
}

const server = new Server().app;

server.set('port', 3000);
server.use(express.urlencoded({ extended: true }));

왜않돼,,? 하다가 코드 위치를 옮겨 봤더니 잘 동작했다..

// Server.ts

class Server {
  // app 타입 지정
  public app: express.Application;

  // 생성자
  constructor() {
    this.app = express();

    this.app.get('/', function (req, res) {
      res.send('Hello 스터D');
    });
  }
}

const server = new Server().app;
server.use(cors()); //모든 cross-origin 요청에 대해 응답
//또는 헤더 설정 use((req, res) => {
//	res.header("Access-Control-Allow-Origin", "*"); // 모든 도메인
//    });

server.set('port', 3000);
server.use(express.urlencoded({ extended: true }));

2. Client 에서 proxy 설정

프록시 서버는 서버와 클라이언트 사이에서 요청을 허용/거부하는 역할을 수행해 Access-Control-Allow-Origin : *의 헤더를 담아 응답해준다고 한다. 중간 단계가 하나 더 생기는 것이기 때문에 속도가 느려지는 단점이 있다.

  • http-proxy-middleware 패키지를 사용
  • package.json 파일에 "proxy": "http://localhost:5000" 추가

출처

profile
프론트가 좋아요

0개의 댓글