[TIL] 2주차 Part8. [예제로 배우는] Node.js의 이해

반 히·2024년 3월 18일

데브코스

목록 보기
12/58
post-thumbnail

📁 CH10. [예제로 배우는] Node.js의 이해

📌 Node.js란

  • Node.js는 자바스크립트를 언어 이상으로 프로그래밍 언어 역할을 할 수 있도록 지원하는 플랫폼. (= 운동장)
  • 즉, 우리는 Node.js를 이용하여 자바스크립트로 백엔드로 구현할 수 있음.

📌 Node.js로 웹서버 만들기

  • require() : Node.js가 가지고 있는 모듈(기능을 할 줄 아는 부품)을 부르는 방법

📌 HTTP 탬플릿

  • Server 파헤치기
let http = require('http');

function onRequest(request, response) {
    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.write('Hello Node.js');
    response.end();
}

http.createServer(onRequest).listen(8888);
//localhost:8888
  • let http = require('http'); : Node.js의 내장 HTTP 모듈을 가져옴. 이 모듈은 HTTP 서버 및 클라이언트를 생성하는데 사용됨.
  • function onRequest(request, response) {} : HTTP 요청이 발생할 때 호출되는 콜백 함수
    • request : 클라이언트로부터 받은 HTTP 요청에 관한 정보를 포함함.
    • response : 클라이언트에 보낼 HTTP 응답을 제어하는 객체.
  • response.writeHead(200, {'Content-Type' : 'text/html'});
    • HTTP 응답 헤더를 작성함
    • 첫 번째 매개변수는 상태 코드.
    • 두 번째 매개변수는 응답의 컨텐츠 타입을 설정함. 'text/html'의 경우 HTML 형식의 데이터를 응답으로 보내는 것을 의미함.
  • response.write('Hello Node.js');
    • HTTP 응답 본문에 텍스트를 작성함.
  • response.end();
    • HTTP 응답을 종료함.
    • 클라이언트가 응답이 끝났다고 인식하기 위해서는 이 메소드가 반드시 호출되어야 함.
  • http.createServer(onRequest).listen(8888);
    • http.createServer()메서드를 사용하여 HTTP 서버를 생성함. 이 메소드는 요청이 있을 때마다 onRequest함수를 호출함
    • listen(8888) 메소드는 서버를 특정 포트(여기서는 8888)에서 대기하도록 설정함.

📌 포트 번호 (port number)

  • 클라이언트와 서버가 대화를 하고 싶다면, 같은 주파수를 맞춰야만 함. 마치 무전기처럼

📌 HTTP 프로토콜 탬플릿

  • Head
    • 1) 통신 상태가 어떤지 알려줌
      • 예를 들어,
        200 : 정상이다
        404 : 클라이언트가 원하는 걸 못 찾겠다
        500 : 서버가 이상하다
      • 우리는 이 숫자들을 HTTP (status) code라고 부름
    • 2) 응답이 어떤 형태인지 적어줌. 예를 들어 html이다.

📌 (server.js 모듈화) 내가 만든 server를 모듈처럼!

  • Node.js가 미리 만들어둔 모듈을 우리가 require('모듈 이름'); 이렇게 사용한 것처럼,
  • 우리가 만든 server도 모듈처럼 다른 javascript 파일에서 사용할 수 있음
//server.js
let http = require('http');

function start() {
    function onRequest(request, response) {
        response.writeHead(200, {'Content-Type' : 'text/html'});
        response.write('Hello Node.js');
        response.end();
    }
    
    http.createServer(onRequest).listen(8888);
    //localhost:8888
}
exports.start = start;
//바깥에서 start 함수를 사용할 수 있게 할 것임.
//index.js
let server = require('./server');

server.start();

📌 Uniform Resource Locator

  • 인터넷 상에서 웹 페이지가 어디있는지 "위치"를 알려주는 주소
  • 쉽게 말해서, 웹 페이지 주소라고 할 수 있음
//server.js
let http = require('http');
let url = require('url');

function start() {
    function onRequest(request, response) {
        let pathname = url.parse(request.url).pathname;
        console.log('pathname : '+ pathname);

        response.writeHead(200, {'Content-Type' : 'text/html'});
        response.write('Hello Node.js');
        response.end();
    }
    
    http.createServer(onRequest).listen(8888);
    //localhost:8888
}
exports.start = start;
//바깥에서 start 함수를 사용할 수 있게 할 것임.
//-->pathname은 http://localhost:8888 뒤에 오는 경로구나!!

  • parhname을 서버가 관리하지 않음 (서버는 할 일이 많아요!! request.. response)
  • 따라서 pathname을 라우터에게 전달해줌
  • 라우터는 어디로 갈지 경로를 정해주는 친구
//server.js
let http = require('http');
let url = require('url');

function start(route) {
    function onRequest(request, response) {
        let pathname = url.parse(request.url).pathname;
        route(pathname);

        response.writeHead(200, {'Content-Type' : 'text/html'});
        response.write('Hello Node.js');
        response.end();
    }
    http.createServer(onRequest).listen(8888);
    //localhost:8888
}

exports.start = start;
//바깥에서 start 함수를 사용할 수 있게 할 것임.
//router.js
function route(pathname) {
    console.log('pathname : '+ pathname);
}

exports.route = route;
//index.js
let server = require('./server');
let router = require('./router');

server.start(router.route);

  • 여기서 pathname은 router.js가 찍어주는 것임!

📌 Sercer와 Router의 역할

  • Server : Request를 받음 (response도)
  • Router : Request의 URL에 따라 루트(route)를 정해줌 = 어디로 갈지 길만 정해줌!
  • 각 루트(route)에서 할 일은 그럼 누가 하나요?
//server.js
let http = require('http');
let url = require('url');

function start(route, handle) {
    function onRequest(request, response) {
        let pathname = url.parse(request.url).pathname;
        route(pathname, handle);

        response.writeHead(200, {'Content-Type' : 'text/html'});
        response.write('Hello Node.js');
        response.end();
    }
    http.createServer(onRequest).listen(8888);
    //localhost:8888
}

exports.start = start;
//바깥에서 start 함수를 사용할 수 있게 할 것임.
//router.js
function route(pathname, handle) {
    console.log('pathname : '+ pathname);

    handle[pathname]();
}
exports.route = route;
//requestHandler.js
function main() {
    console.log('main');
}

function login() {
    console.log('login');
}

let handle = {}; // key:value (사전같은...)
handle['/'] = main;
handle['/login'] = login; 

exports.handle = handle; //exports하면서 함수처럼 됨...
//index.js
let server = require('./server');
let router = require('./router');
let requestHandler = require('./requestHandler');

server.start(router.route, requestHandler.handle);

!!!favicon

  • favorites icon의 약자로 웹 페이지나 웹 사이트를 대표하는 아이콘
  • 웹 브라우저는 페이지를 요청할 때 자동으로 favicon을 요청하는데, 우리는 favicon이 존재하지 않기 때문에 이와 같은 에러가 발생하는 것임
  • 해결하는 방법은 favicon.ico를 만들어서 제공해주는 방법이 있고, favicon 요청이 들어왔을 때 요청을 씹어버리는 방법이 있음.
if (pathname === '/favicon.ico') {
	response.writeHead(200, { 'Content-Type': 'image/x-icon' });
  return response.end();
}
//추가해서 오류 수정

📌 Url에 따라 프론트엔드에 다른 response 보내기

  • 서버가 하는 일이 많음
  • requestHandler
    • requestHandler는 라우터가 루트를 지정을 해주는, 그 루트에서 할 일을 정해주는 친구
  • 어디 경로로 갈지 정래주는 것은 라우터
//server.js
let http = require('http');
let url = require('url');

function start(route, handle) {
    function onRequest(request, response) {
        let pathname = url.parse(request.url).pathname;
        route(pathname, handle, response);
    }
    http.createServer(onRequest).listen(8888);
    //localhost:8888
}
exports.start = start;
//바깥에서 start 함수를 사용할 수 있게 할 것임
//router.js
function route(pathname, handle, response) {
	if (pathname === '/favicon.ico') {
		response.writeHead(200, { 'Content-Type': 'image/x-icon' });
		return response.end();
    }
    console.log('pathname : '+ pathname);

    if (typeof handle[pathname] == 'function') {
        handle[pathname](response);
    } else {
        response.writeHead(404, {'Content-Type' : 'text/html'});
        response.write('Not Found.');
        response.end();
    }
}
exports.route = route;
//index.js
let server = require('./server');
let router = require('./router');
let requestHandler = require('./requestHandler');

server.start(router.route, requestHandler.handle);
//requestHandler.js
function main(response) {
    console.log('main');
    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.write('Main page');
    response.end();
}
function login(response) {
    console.log('login');

    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.write('Login page');
    response.end();
}

let handle = {}; // key:value (사전같은...)
handle['/'] = main;
handle['/login'] = login; 

exports.handle = handle; //exports하면서 함수처럼 됨...

0개의 댓글