Node

멤버 CRUD_ cors, json 파싱, 포트번호 설정. 라우팅

wintertreey 2024. 8. 13. 13:07

c:\work2\node_ex>mkdir nodeserver1

>cd nodeserver1

 

>npm init

>npm i express

>npm i --save-dev nodemon

>npm i cors

 

다음은 폴더를 생성하고, 프로젝트를 생성시 설치한 모듈이다.

 

  • express: Node.js에서 서버를 쉽게 구축할 수 있도록 도와주는 웹 프레임워크입니다. 간단한 라우팅, 미들웨어, 요청 처리 등을 지원합니다.
  • nodemon: 개발 중에 파일 변경 시 자동으로 서버를 재시작해주는 도구입니다. 코드 변경 사항을 즉시 반영할 수 있어 개발이 용이합니다.
  • cors: Cross-Origin Resource Sharing의 약자로, 서로 다른 출처(도메인) 간의 자원 공유를 허용하도록 서버를 설정하는 미들웨어입니다. 웹 애플리케이션이 다른 도메인에서 자원을 요청할 수 있도록 합니다.

 

 

start 스크립트를 정의하는 부분

 

  1. 자동 재시작: nodemon은 파일 시스템을 모니터링하여 파일에 변경이 생길 때마다 서버를 자동으로 재시작합니다. 개발 중에는 코드가 자주 변경되기 때문에 서버를 수동으로 재시작할 필요 없이, nodemon이 자동으로 이를 처리해 줍니다.
  2. 편리한 실행: npm start 명령어를 실행하면 nodemon app.mjs가 실행됩니다. 이렇게 하면 복잡한 명령어를 직접 입력할 필요 없이 간편하게 서버를 시작할 수 있습니다.

결과적으로, 이 설정은 개발 효율성을 높이고 서버 관리를 쉽게 해줍니다.

 

 

cors, json 파싱, 포트번호 설정

import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import cors from 'cors';

const app = express();

app.use(cors()) // cors 미들웨어 등록: cors해킹에서 벗어날 수 있다. for service.
app.use(express.json()); // express.join 미들웨어: json 파싱용
// 예: 클라이언트가 json 데이터를 요청(post)으로 보낼때 
//{"name":"tom", "age":30} 를 자동으로 파싱해 req.body 객체를 만듦.
// req.body.name 또는 req.body.age로 접근이 가능해짐. 
app.set('port', process.env.PORT || 3000); //포트 설정

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

//정적 파일 제공 폴더 정의
app.use(express.static(path.join(__dirname, 'public')));


app.listen(app.get('port'), () => {
    console.log(app.get('port'), '번 포트로 서버서비스 중..');
});

 

 

 

라우팅작업

import gogekRouter from './routes/gogek.mjs';
import jikwonRouter from './routes/jikwon.mjs';

//라우팅작업. 따로 만들어서 호출.
app.use('/', jikwonRouter);
app.use('/gogek', gogekRouter);

라우팅 잘된 것 확인.

 


본격적으로 파일을 이동하며 정보를 받아보자. 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>텔레토비 동산🌈 구성원</h1>
    <ul id="emp-list"></ul>
    <div>
        get : <button id="get-emps">멤버리스트 요청 get</button>
    </div>
    <div>
        post : <input type="text" id="emp-name" placeholder="멤버이름 입력" required>
        <button id="add-emp">친구 추가</button>
    </div>

    <script>
    document.addEventListener("DOMContentLoaded", () => {
        const empList = document.getElementById("emp-list");
        const empNameInput = document.getElementById("emp-name");
        const getEmpbutton = document.getElementById("get-emps");
        const addEmpbutton = document.getElementById("add-emp");

        //get 요청으로 직원 정보 읽기
        getEmpbutton.addEventListener('click', () => {
            fetch('/employees')
            .then(response => response.json())
            .then(data => {
                empList.innerHTML = ''; //출력장소 초기화
                data.forEach(emp => {
                    const li = document.createElement("li"); //li태그에 담고
                    li.textContent = emp.name; //이름만
                    empList.appendChild(li); //id emplist에 li태그를 넣어줌
                });
            })
            .catch(error => console.error('에러발생: ', error));
        });

         //get 요청으로 직원 정보 읽기
         addEmpbutton.addEventListener('click', () => {
            const newEmp = {id:Date.now(), name:empNameInput.value};

            fetch('/employees', {
                method:'POST',
                headers:{
                    'Content-Type':'application/json'
                },
                body:JSON.stringify(newEmp) //전송시 js객체를 json문자열로 변환 후 전송
            })
            .then(response => response.json())
            .then(emp => {
                    const li = document.createElement("li"); //li태그에 담고
                    li.textContent = emp.name; //이름만
                    empList.appendChild(li); //id emplist에 li태그를 넣어줌
                    empNameInput.value = '';// 입력필드 초기화

            })
            .catch(error => console.error('추가에러: ', error));
         });
// let stu = {name:'tom', age:22}가정 ->stringify(stu)-> {'name':'tom','age':22} 
//즉 json모양을 하지만 string으로 변환. 타입 object -> String으로 변환됨. 

    });
    </script>
</body>
</html>

 

 

abc.html에 넘겨줄 json 정보 만들기.

import { Router } from "express";
import path from 'path';
import { fileURLToPath } from 'url';

const  router = Router();

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

router.get('/', (req, res) => {
    //res.send('HELLO, jikwon');
    res.sendFile(path.join(__dirname, '../public/abc.html'));
});

const employees = [
    {id:1, name:'보라돌이'},
    {id:2, name:'뚜비'},
    {id:3, name:'나나'},
    {id:4, name:'뽀'}
];

router.get('/employees', (req, res) => {
    res.json(employees);
});
router.post('/employees', (req, res) => {
    const newEmployee = req.body;
    if(!newEmployee || !newEmployee.name){
        return res.status(400).json({error:'잘못된 데이터!'});
    }
    employees.push(newEmployee);
    res.status(201).json(newEmployee); // 201:created 요청은 성공적. POST요청 후 새로운 리소스가 생성되었을때 사용.
    
});
export default router;

get 버튼 누르기전

status

보통 자주 마주하는건, 경로설정 문제 404. 에러발생시 500. 

404(Not Found, 찾을 수 없음): 서버가 요청한 페이지(Resource)를 찾을 수 없다. 예를 들어 서버에 존재하지 않는 페이지에 대한 요청이 있을 경우 서버는 이 코드를 제공한다.

500(내부 서버 오류): 서버에 오류가 발생하여 요청을 수행할 수 없다.

 

 

200(성공): 서버가 요청을 제대로 처리했다는 뜻이다. 이는 주로 서버가 요청한 페이지를 제공했다는 의미로 쓰인다. 201(작성됨): 성공적으로 요청되었으며 서버가 새 리소스를 작성했다.

202(허용됨): 서버가 요청을 접수했지만 아직 처리하지 않았다.

400(잘못된 요청): 서버가 요청의 구문을 인식하지 못했다.

 

 

 

 

 

 

 


 

https://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C

 

HTTP 상태 코드 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 아래는 HTTP(하이퍼텍스트 전송 프로토콜) 응답 상태 코드의 목록이다. IANA가 현재 공식 HTTP 상태 코드 레지스트리를 관리하고 있다. 모든 HTTP 응답 코드는 5개의

ko.wikipedia.org