React.js와 Node.js를 활용한 TODO List 개발: CORS 문제와 해결 방안
React.js와 Node.js를 활용한 TODO List 개발: CORS 문제를 해결하는 시나리오
React.js와 Node.js로 간단한 TODO List 애플리케이션을 개발할 때 CORS(Cross-Origin Resource Sharing) 문제가 발생하는 상황을 직접 경험하며 해결하는 방법을 알아보겠습니다. 이 시나리오는 CORS 설정을 생략한 상태에서 시작하여 오류를 디버깅하고, CORS 패키지를 설치하고 적용하는 과정을 다룹니다.
📌 프로젝트 개요 및 목표
목표
- React.js를 이용해 TODO List UI를 개발.
- Node.js(Express)를 이용해 RESTful API 서버 구성.
- CORS 오류를 직접 경험하고 이를 해결하는 방법 익히기.
프로젝트 구조
react-node-todo/
├── backend/ # Node.js 서버 코드
├── frontend/ # React.js 클라이언트 코드
🔧 프로젝트 설치 및 초기화
1. Node.js와 npm 설치 확인
먼저, Node.js와 npm이 설치되어 있는지 확인합니다.
node -v
npm -v
설치되지 않았다면 Node.js 공식 웹사이트에서 최신 버전을 다운로드하세요.
2. 프로젝트 디렉터리 생성
mkdir react-node-todo
cd react-node-todo
mkdir frontend backend
🛠️ 백엔드(Node.js) 설정
1. 백엔드 초기화 및 패키지 설치
cd backend
npm init -y
npm install express
2. server.js
생성 및 작성
backend/server.js
파일을 생성하고 다음 코드를 작성합니다:
const express = require('express');
const app = express();
app.use(express.json()); // JSON 요청 처리
let todos = []; // 메모리 데이터베이스
// GET: 모든 TODO 조회
app.get('/api/todos', (req, res) => {
res.json(todos);
});
// POST: 새로운 TODO 추가
app.post('/api/todos', (req, res) => {
const { text } = req.body;
if (!text) return res.status(400).json({ error: 'Text is required' });
const newTodo = { id: todos.length + 1, text };
todos.push(newTodo);
res.json(newTodo);
});
const PORT = 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
3. 서버 실행
node server.js
🎨 프론트엔드(React.js) 설정
1. React 프로젝트 초기화
cd ../frontend
npx create-react-app .
npm install axios
2. TODO List 컴포넌트 생성
frontend/src/components/TodoList.js
를 생성하고 다음 코드를 작성합니다:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const TodoList = () => {
const [todos, setTodos] = useState([]);
const [newTodo, setNewTodo] = useState('');
// 서버에서 TODO 가져오기
useEffect(() => {
axios.get('http://localhost:5000/api/todos')
.then(response => setTodos(response.data))
.catch(error => console.error('Error fetching todos:', error));
}, []);
// 새로운 TODO 추가
const addTodo = () => {
axios.post('http://localhost:5000/api/todos', { text: newTodo })
.then(response => {
setTodos([...todos, response.data]);
setNewTodo('');
})
.catch(error => console.error('Error adding todo:', error));
};
return (
<div>
<h1>TODO List</h1>
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
<input
type="text"
value={newTodo}
onChange={(e) => setNewTodo(e.target.value)}
placeholder="Enter a new TODO"
/>
<button onClick={addTodo}>Add TODO</button>
</div>
);
};
export default TodoList;
3. App.js에 컴포넌트 추가
import React from 'react';
import TodoList from './components/TodoList';
function App() {
return (
<div className="App">
<TodoList />
</div>
);
}
export default App;
🚨 CORS 문제 시나리오
1. 오류 발생
React 앱을 실행하고 브라우저 개발자 도구의 콘솔에서 다음과 같은 오류를 확인할 수 있습니다:
Access to XMLHttpRequest at 'http://localhost:5000/api/todos'
from origin 'http://localhost:3000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
2. 원인 분석
React 클라이언트(localhost:3000
)와 Node.js 서버(localhost:5000
)는 서로 다른 도메인에서 실행되기 때문에, 브라우저는 보안상의 이유로 요청을 차단합니다.
✅ CORS 문제 해결
1. CORS 패키지 설치
Node.js 백엔드에 CORS 패키지를 설치합니다:
npm install cors
2. server.js
에 CORS 설정 추가
server.js
파일을 수정하여 CORS 설정을 추가합니다:
const cors = require('cors');
app.use(cors()); // 모든 도메인 허용
3. 특정 도메인만 허용 (선택 사항)
특정 도메인만 허용하고 싶다면 다음과 같이 설정합니다:
app.use(cors({
origin: 'http://localhost:3000', // React 앱 도메인
methods: ['GET', 'POST'], // 허용할 메서드
}));
🚀 실행 및 확인
1. 백엔드 실행
cd backend
node server.js
2. 프론트엔드 실행
cd frontend
npm start
3. 브라우저에서 확인
React 앱에서 TODO를 추가하고 목록을 확인하세요. CORS 오류가 해결된 상태로 요청이 정상적으로 처리됩니다.
🔍 주니어 개발자를 위한 팁
- CORS 문제를 학습 기회로 활용하세요
CORS는 초보 개발자가 자주 마주하는 문제입니다. 직접 해결 과정을 경험하며 보안 정책의 중요성을 이해할 수 있습니다. - 디버깅 습관 기르기
- 브라우저 개발자 도구의 네트워크 탭과 콘솔에서 요청과 응답을 확인하세요.
- Node.js 서버 로그를 확인하여 요청이 제대로 처리되는지 파악하세요.
- 프록시 설정 활용
React 개발 환경에서만 사용할 경우,package.json
파일에 프록시 설정을 추가하여 문제를 임시로 해결할 수 있습니다: "proxy": "http://localhost:5000"
✅ 결론
이 시나리오에서는 CORS 설정을 생략한 상태에서 발생하는 문제를 해결하며, Node.js와 React.js 간의 통신을 안정적으로 구성하는 방법을 배웠습니다.
- CORS 문제는 보안 정책을 이해하는 중요한 기회가 됩니다.
- 백엔드와 프론트엔드를 협력적으로 개발하는 기술을 익힐 수 있습니다.
🎯 추가 과제
- TODO 삭제 기능 추가.
- MongoDB를 연동하여 데이터 저장.
🔗 관련 태그
- react.js
- node.js
- todo-list
- cors-문제
- axios
CORS 가 왜 생겼고, 왜 필요한가요?
https://aspdotnet.tistory.com/3327