[React] Axios로 Express 서버와 연동하기 (2) GET으로 데이터 받기, CORS 에러 해결

쥬롬의 코드착즙기·2022년 11월 1일
0

TIL : Today I learned

목록 보기
5/10
post-thumbnail
post-custom-banner

본문은 라매개발자 강의 프론트에서 서버에 데이터 요청하는 방법 (React로 fetch, axios 사용하기)를 기반으로 작성되었습니다.

📌 CLIENT

⚛ Create-react-app

client 폴더로 이동 후 콘솔창에서 create-react-app을 통해 리액트 초기세팅을 해주자.

npx create-react-app .

안 쓸 파일들은 지워주자.

App.js와 index.js에서 방금 지운 .css 파일이나 logo.svg 파일을 import하는 부분을 지워준다.

App.js를 수정해서 화면에 TODO LIST가 보이도록 한다.

App.js

function App() {
  return (
    <div className="App">
      <h1>TODO LIST</h1>
    </div>
  );
}

export default App;

콘솔창에 npm start를 했을 때 화면에 TODO LIST가 대문짝만하게 나온다면 성공!
npm start

👋 서버에 데이터 요청

서버에 데이터 요청하는 방법은 react 기본 제공 fetch를 이용하는 방법이 있고, axios 라이브러리를 활용하는 방법이 있다.

서버에 데이터를 요청하기 위해 꼭 알아야 하는 것은
📌서버 주소
📌http 메소드 (get, post, ...)
이다. 이 두 가지는 어떤 방법을 써도 필요하다.

✏ fetch

먼저... 지난번에 만들었던 서버 포트가 3000번이었는데,
현재 클라이언트에서 3000번 포트를 사용하고 있다.
(주소창에서 localhost:3000이라고 나오면 3000번 포트를 사용하고 있는 것)

server 폴더의 app.js 가장 하단에 있는 서버 포트를 4000번으로 수정해 준다.

app.listen(4000,()=>{
    console.log("server start!");
})

포트를 다르게 해 줬으니 서로 데이터를 주고받을 수 있다.
client 폴더의 App.js로 돌아와서 fetch를 이용해 데이터를 받아보자.

function App(){
  fetch('https://localhost:4000/api/todo')
  .then((res)=>res.json());
  .then((data)=>console.log(data));
  return(
    /*이하 생략*/

서버로부터 데이터를 받아 와서 콘솔에 출력시키는 것이 목표이다.

서버도 켜 주자. 서버 폴더에서 콘솔창을 통해 서버를 실행시켜 준다.

node app.js

실행시켜 보면...
안된다.

잘 읽어 보면 ~ has been blocked by CORS policy. 라는 내용이 있다.
CORS 에러는 자주 나온다. 또 만나면 한번에 박살낼 수 있게 무엇인지 알고 넘어가자.

❌ CORS 에러?

CORS는 Cross Origin Resource Share의 약자이다.
여기서 Origin은 서로 다른 호스트와 포트를 포함한 데이터의 출처를 말한다.
데이터 교환을 할 때 서로 다른 Origin을 가지고 있으면 함부로 통신하면 안 된다.
시험공부 할 때 내 필기와 다른 학생의 필기를 함부로 볼 수 없듯이...!!

CORS 정책은 일단 Origin이 다르면 데이터 통신을 막는다.
따라서 필요한 경우 데이터를 보내 주는 서버에서 CORS를 허용해 주어야 한다.
필기를 보여주는 학생이 ㅇㅋ! 해야 볼 수 있는 것처럼!

🧹 서버에서 CORS 에러를 해결해보자

방법은 간단하다. 이미 cors를 해결해주는 미들웨어가 존재한다. 세상 좋다...
서버에 cors를 설치해 주고, 미들웨어 코드를 추가해 준다.

콘솔창

npm i cors

app.js

const cors = require('cors');

app.use(cors());

그럼 받아온 데이터를 콘솔창에서 확인할 수 있다.

📌전체 코드

/client/App.js

function App() {
  fetch('http://localhost:4000/api/todo')
  .then((res)=>res.json())
  .then((data)=>console.log(data));

  return (
    <div className="App">
      <h1>TODO LIST</h1>
    </div>
  );
}

export default App;

/server/app.js

const express = require('express')
const app = express()
const cors = require('cors')
const bodyParser = require('body-parser')

app.use(cors());

app.use(bodyParser.json()) // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })) // for parsing application/x-www-form-urlencoded

const todoList = [{
    id:1,
    text:"todo1",
    done: false,
}];

app.get('/', function (req, res) {
  res.send('Hello World')
})

app.get('/api/todo',(req,res)=>{
    res.json(todoList);
})

app.post('/api/todo',(req,res)=>{
    const {text, done} = req.body; //body에 text와 done을 담아보냄
    todoList.post({
        id:id++,
        text,
        done,
    })
}

)
app.listen(4000,()=>{
    console.log("server start!");
})
profile
코드를 짭니다...
post-custom-banner

1개의 댓글

comment-user-thumbnail
2024년 3월 10일

잘 보고 갑니다 :-)

답글 달기