본문 바로가기

4. Node.js | React.js

4/21(금) IT K-DT(37일차) / 22.POST~26.CORS

 

22. post

 HTTP 프로토콜의 메서드 중 하나로,

 요청을 통해 전송된 데이터를 서버에서 처리하고, 필요한 경우 데이터베이스와 상호 작용하거나 다른 작업을 수행할 수 있음.

 예를 들어, 웹 애플리케이션에서 로그인 폼을 작성하고 제출할 때,

 사용자가 입력한 정보를 서버로 전송하려면 'POST' 메서드를 사용할 수 있음.

 'POST' 메서드를 사용하면 클라이언트가 서버로 보낸 데이터가 URL에 노출되지 않기 때문에,

 보안적으로 안전한 방법으로 데이터를 전송할 수 있음.

 'POST' 메서드를 처리하기 위해서는 HTTP 모듈을 사용하거나 Express를 사용할 수 있음.

 


import express from 'express';

const app = express();

app .use(express.json()); // body를 통한 data의 수신이 가능하게 함.

app .post('/posts', (req, res) => {  
    console.log(req.body);
    res.status(201).send('Create 되었습니다!'); // 응답번호. create에 대해서는 보통 201번의 번호를 부여.
});

app .listen(8080);

 

 Postman에서 localhost:8080/posts를 입력하여 create를 확인.

 

 

23. error-handling

프로그램에서 예상치 못한 오류가 발생했을 때 이를 적절하게 처리하는 것.

예를 들어, 프로그램이 실행되는 도중에 파일을 열 때 파일이 존재하지 않는다면, 이는 에러가 발생한 것.

이때, 에러를 적절하게 처리하지 않으면 프로그램이 중단.

에러 핸들링은 프로그램의 안정성과 신뢰성을 높이는 중요한 요소.

에러 핸들링은 다음과 같은 방법으로 수행할 수 있습니다.

에러 핸들링은 프로그래밍 언어나 프레임워크마다 다른 방식으로 처리될 수 있음. 

try-catch문, 에러 코드 반환 등의 방식을 사용하여 에러 핸들링을 수행할 수 있음.

 


import express from 'express';
import fs from 'fs';

const app = express();

app.use(express.json()); // body가 전송되었을 때 미들웨어로 등록

app.get('/file1', (req, res) => {                  // 사용자가 get방식으로 들어옴
    fs.readFile('/file1.txt', (err, data) => {
        if(err){
            res.sendStatus(404);
        }
    });
});

app.use((error, req, res, next) => {
    console.error(error);
    res.sendStatus(500).join({message:'서버 에러'});    
});

app.listen(9090);


예) file2.txt 파일이 없는 상황의 error를 처리하는 예제.

try-catch문을 작성.

 


app.get('/file2', (req, res)=>{
    try{
        const data = fs.readFileSync('/file2.txt');  // readFileSync(): file을 동기식으로 읽어오는 메서드
        }catch(error){
            res.sendStatus(404);
        }
});

app.listen(9090);

 


예) file3.txt 파일이 없는 상황의 error를 처리하는 예제. (fs/promises로부터 Async를 이용)

try-catch문에서 catch를 추가하여 작성.


import fsAsync from 'fs/promises';

app.get('/file3', (req, res)=>{
    fsAsync
        .readFile('/file3.txt')
        .catch((error) => {
            res.sendStatus(404);
        });
});

app.listen(9090);



예) file4.txt 파일이 없는 상황의 error를 처리하는 예제. (async와 await를 이용)


app.get('/file4', async (req, res)=>{
    try{
        const data = await fsAsync.readFile('/file4.txt');
    }catch(error){
            res.sendStatus(404);
        }
});

app.listen(9090);

 

24. route

 클라이언트 요청을 서버에서 처리하는 방법을 정의.

 즉, 클라이언트가 서버에 요청을 보낼 때, 해당 요청이 어떤 함수나 모듈에서 처리될지를 결정함.

 HTTP 메서드와 URL 패턴을 기반으로 동작함.

 예를 들어, 클라이언트가 "/users" URL로 GET 요청을 보내는 경우, 이 요청을 처리하기 위한 라우트를 정의

 할 수 있음.

 

예) Express를 사용하여 /posts와 /posts/:id라우트에 대한 GET, POST, PUT, DELETE 요청을 처리하는 예제.


import express from 'express';


const app = express();

app                       // '메소드체이닝'을 이용
    .route('/posts')       //  URL 경로에 대한 라우트를 정의
    .get((req, res) => {
        res.status(200).send('GET: /posts');
    })
    .post((req, res) => {
    res.status(201).send('POST: /posts');
    });

app 
    .route('/posts/:id')    //  URL 경로에 대한 라우트를 정의
    .put((req, res) => {
        res.status(201).send('PUT: /posts/:id'); 
})
    .delete((req, res) => {
        res.status(200).send('DELETE: /posts/:id');
});

app .listen(9090);

 

 

예) Express를 사용하여 /posts와 /users URL 경로에 대한 요청을 처리하기 위한 라우터를 정의하고, 

      JSON 형태의 요청 데이터를 파싱하여 처리하는 예제


import express from 'express';
import postRouter from './routes/post.js';
import userRouter from './routes/user.js';


const app = express();

app .use(express.json());
app .use('/posts', postRouter);
app .use('/users', userRouter);


app .listen(8080);

routes라는 폴더를 생성하여 post.js, user.js 파일을 내부에 생성.


post.js

import express from 'express';

const router = express.Router();

    router .use((req,res,next)=>{
        console.log('post에 존재하는 미들웨어');
        next();
    });

    router .get("/", (req, res) => {
        res.status(200).send('GET: /posts');
    });

    router .post("/", (req, res) => {
        res.status(201).send('POST: /posts');
    });

    router .put("/:id", (req, res) => {
        res.status(201).send('PUT: /posts/:id');
    });

    router .delete("/:id", (req, res) => {
        res.status(200).send('DELETE: /posts/:id');
    });

    export default router; // 모듈을 내보내기하는 기능.


user.js

import express from 'express';

const router = express.Router();

router.use((req,res,next)=>{
    console.log('users에 존재하는 미들웨어');
    next();
});

router.get("/", (req, res) => {
    res.status(200).send('GET: /users');
});

router.post("/", (req, res) => {
res.status(201).send('POST: /users');
});

router.put("/:id", (req, res) => {
    res.status(201).send('PUT: /users/:id');
});

router.delete("/:id", (req, res) => {
    res.status(200).send('DELETE: /users/:id');
});

    export default router; // 모듈을 내보내기하는 기능.

 

25. public

웹 애플리케이션에서 정적 파일(예: HTML, CSS, JavaScript, 이미지 등)을 저장하는 기본 디렉토리 이름. 

이 디렉토리는 웹 애플리케이션에 접근할 때 필요한 파일들을 저장하기 위해 사용됨.

즉, public폴더에 존재하는 이미지, 파일을 rest를 사용하지 않고 사용자가 직접 접근할 수 있게 해주는 기능.

 

static()

사용자를 원하는 리소스에 직접 접근할 수 있게 해주는 메서드. 미들웨어.

 

 예제) index.html과 news.png를 보고싶은 경우

▲ index.html

▲ news.png

▲ 해당 파일들을 public 폴더안에 넣음


import express from 'express';

const app = express();

app.use(express.json());

app.get('/', (req, res)=> {
    console.log('/get으로 실행');
    res.status(200).send('get으로 첫 페이지 실행');
});


app.use('/files', express.static('public'))  // 경로를 직접 만들어서 보여줌.
app.listen(9090);

 app.use(express.static('public'))
 app.use(express.static('css')) 
 app.use(express.static('html'))

위와 같이 css파일이 있는 폴더, html파일이 있는 폴더로 접근이 가능하게 해줌.

 

26. CORS

웹 브라우저에서 발생하는 보안 정책.

다른 도메인이 리소스를 요청하는 경우 안전하게 처리되는지, 다른 도메인에서 온 것인지,

보안 정책을 준수하는지 여부 등을 검사하여 접근 권한을 부여.

일반적으로 웹 API를 사용할 때 발생하는 문제를 해결하기 위해 사용됨.

예를 들어, JavaScript 코드에서 다른 도메인의 API에 요청을 보내는 경우, 보안 정책에 따라 차단할 수 있음.

CORS는 서버 측에서 Access-Control-Allow-Origin이라는 헤더를 사용하여 요청을 허용할지 여부를 결정.

이 헤더는 허용할 도메인의 URL뿐만 아니라,

요청을 보내는 메서드(GET, POST, PUT, DELETE 등)와 허용할 헤더(Content-Type, Authorization 등)도

지정할 수 있음.

CORS는 보안상 중요한 이슈이며, 서버 개발자들은 이를 고려하여 API를 설계하고 구현해야 함.

 

예) 


JavaScript


import express from 'express';
const app = express();

app.use((req, res, next)=> {
    res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500'); 
    // access-control-allow-origin의 header를 생성.
    res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT, DELETE'); 
   // 4개의 Methods가 header에 들어올 수 있도록 허용.
    next();
})

app.get('/', (req, res)=>{
    res.send('Welcome');
});

app.listen(9090);

HTML

<body>
    <h2>6-cos</h2>
    <p>프론트엔드로 사용할 6-cos.html</p>

    <script>
        fetch('http://localhost:9090/', {method:'GET'})
        .then(console.log)
        .catch(console.error);
    </script>
</body>

 

 

예)


import express from 'express';
import morgan from 'morgan'; // 사용자가 서버에 들어올 때마다 정보를 제공하는 라이브러리. npm i morgan으로 설치
import cors from 'cors';


const app = express();

app.use(morgan('common')); // 제공되는 정보의 양에 대한 차이.
app.use(cors());

app.get('/', (req, res)=> {
    console.log('/get으로 메인페이지 호출');
    res.send('Welcome');
});

app.listen(9090);


 

과제

팀단위로 react.js를 공부한 후, 틱택토게임의 예제를 만들어보기.

 

참고사이트: https://ko.legacy.reactjs.org/

 

React – 사용자 인터페이스를 만들기 위한 JavaScript 라이브러리

A JavaScript library for building user interfaces

ko.legacy.reactjs.org