React 로 구성한 클라이언트 환경에서, 서버와의 통신을 통해 데이터를 받아오기 위해서 fetch 또는 axios 를 사용합니다.
이 글은 각 방법에 대해 알아보고 제 프로젝트에 적용시킨 과정을 정리한 글입니다.
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))
Node.js와 브라우저를 위한 Promise 기반 HTTP 비동기 통신 라이브러리
react를 사용 시 fetch 보다 axios 를 많이 사용하는 이유?
npm install -D axios
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',
};
// src/util/api.ts
//집가서 복붙해야댐..
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 에 셋팅된다.
}),
],
CORS 는 도메인 및 프로토콜, 포트가 다른 서버의 자원을 요청하면 발생하는 이슈이다.
client : localhost:9000
, server : localhost:3000
로 분리하여 개발하고 있기 때문에 포트가 달라져서 CORS 가 발생한 것 같다.
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 }));
했는데 안된다..?
// 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 }));
프록시 서버는 서버와 클라이언트 사이에서 요청을 허용/거부하는 역할을 수행해 Access-Control-Allow-Origin : *의 헤더를 담아 응답해준다고 한다. 중간 단계가 하나 더 생기는 것이기 때문에 속도가 느려지는 단점이 있다.
http-proxy-middleware
패키지를 사용"proxy": "http://localhost:5000"
추가출처