nodejs가 왜 나오게 되었으며, 어떻게 사용되고 있는지 웹을 배경으로 정리해보도록 하겠습니다.

Node.js란?

nodejs는 웹 서버로서 사용될 수 있습니다. 웹 서버는 것은 사용자가 특정 URL에 들어왔을 때 그에 맞는 리소스 를 제공해줍니다. 그렇다면 URL은 어떻게 구성이 되어있을까요?

image

URL은 위의 이미지 처럼 구성이 되어있으며, ? 뒤에 나오고 &로 연결되어있는 query string이 중요한 역할을 해줍니다.

node는 html을 반복적으로 작성하는 불편함을 해결하고자 하는 생각을 기초로 만들어졌습니다.

기존에 index.html , 1.html , 2.html , 3.html 과 같이 중복된 파일을 만들어야하고 이에 따라 발생하는 유지보수 비용이 심했기 때문에 url에 따라 다른 정보가 있다면 그 정보만 변경해주는 방식으로 작성해주는게 훨씬 편함

url에 있는 query string의 변화에 따라 변수를 설정해주면 동적인 웹사이트를 작성할 수 있음.

node는 왜 나오게 되었는가?

HTML을 템플릿 처럼 사용하기

fileSystem

웹 서버의 200,404응답

nodejs에서의 url모듈에서 현재 request.urlparse하게 되면 아래와 같은 정보가 나온게 됩니다.

Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: '?id=HTML',
  query: [Object: null prototype] { id: 'HTML' },
  pathname: '/',
  path: '/?id=HTML',
  href: '/?id=HTML' }

여기서 path현재 모든 경로를 나타내고 pathnamequerystring을 제외한 경로를 나타냅니다 .그렇다면 pathname/이 아닐경우에 404페이지를 보여주면 될 것 같습니다.

var http = require("http");
var fs = require("fs");
var url = require("url");
var app = http.createServer(function(request, response) {
  var _url = request.url;
  var queryData = url.parse(_url, true).query;
  var title = queryData.id;
  if (_url == "/") {
    title = "welcome";
  }
  console.log(_url);
  if (url.parse(_url, true).pathname == "/") {
    fs.readFile(`./data/${title}`, function(err, desc) {
      var template = `
      <!DOCTYPE html>
      <html>
        <head>
          <title>WEB1 - HTML</title>
          <meta charset="utf-8" />
        </head>
        <body>
          <h1><a href="/">WEB</a></h1>
          <ol>
            <li><a href="/?id=HTML">HTML</a></li>
            <li><a href="/?id=CSS">CSS</a></li>
            <li><a href="/?id=JavaScript">JavaScript</a></li>
          </ol>
          <h2>${title}</h2>
          <p>
            <a href="https://www.w3.org/TR/html5/" target="_blank" title="html5 speicification">Hypertext Markup Language (HTML)</a> is the standard markup language for
            <strong>creating <u>web</u> pages</strong> and web applications.Web browsers receive HTML documents from a web server or from local storage and render them into multimedia web pages. HTML
            describes the structure of a web page semantically and originally included cues for the appearance of the document.
            <img src="coding.jpg" width="100%" />
          </p>
          <p style="margin-top:45px;">
            ${desc}
          </p>
        </body>
      </html>
      
      `;

      response.end(template);
    });
  } else {
    response.end("404 Not Found");
  }

  response.writeHead(200);
});
app.listen(3000);

이렇게 작성할 경우 localhost:3000/외에 모든 주소에서는 “404 Not Found”라는 글을 볼 수 있습니다.

이런 방식으로 nodejs에서 즉 웹 서버에서 사용자가 요청한 url에 따라서 응답에 대한 성공 실패를 코드로 작성할 수 있습니다.

노드 모듈의 함수의 콜백함수들은 비동기로 동작하기 때문에 아래와 같이 콘솔

var express = require("express");
var app = express();

app.listen(3000, function() {
  console.log("start");
});

console.log("end of server");
// end of server
// start

App.js가 수정 됐을 때 자동으로 감지하여 서버를 리로드 해주는 모듈 은 nodemon사용

$ npm install nodemon -g 
$ nodemon app.js

브라우저에서 get요청이 왔을 경우 express서버에서 get메소드를 사용해서 응답을 해결할 수 있음.

var express = require("express");
var app = express();

app.listen(3000, function() {
  console.log("start");
});
// 브라우저 Url이 '/'로 get요청이 들어오면 해당 callback 함수로 동작함 해당 함수는 비동기 형태로 동작함.
app.get("/", function(req, res) {
  res.sendFile(__dirname + "/index.html");
});

노드에서 현재 경로를 사용하고 싶다면 __dirname을 사용하면 됨.

Main.js 를 만들어서 main.html 에서 사용할 경우 크롬 확장 프로그램의 네트워크 탭에서 에러가 발생함. 왜냐하면 localhost:3000/public/main.js에 대한 url routing이 되어있지 않기 떄문임.

모든 static url에 대해서 url routing을 해주기에는 너무 번거로움. 이것을 해결하기 위해서 express의 use메소드를 사용하면 됨 .

var express = require("express");
var app = express();

app.listen(3000, function() {
  console.log("start");
});
// urlrouting
app.use(express.static("public"));
app.get("/", function(req, res) {
  res.sendFile(__dirname + "/public/main.html");
});

브라우저에서 form 을 통해서 해당 url에 대한 post요청이 들어왔을 경우 post메소드를 사용해서 작성하면 됨.

body-parserreq.body프로퍼티를 사용할 수 있게 해줌. post,put요청 메소드의 req.body를 읽어올 수 없음 .

express문서에는 미들웨어 없이 post,put과 같은 요청의 req.body에 접근하게 되면 기본적으로 undefined 를 리턴한다. bodyparser혹은 multer와 같은 미들웨어를 사용해야한다.

간단하게 얘기하면 api 요청에서 받은 값을 원하는 형태로 파싱할 수 있도록 도와주는 미들웨어 인 셈이다.

var express = require("express");
var app = express();
var bodyParser = require("body-parser");
app.listen(3000, function() {
  console.log("start");
});
// urlrouting
app.use(express.static("public"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.get("/", function(req, res) {
  res.sendFile(__dirname + "/public/main.html");
});

app.post("/email_post", function(req, res) {
  var body = "";
  body = req.body.email;
  res.send(`<h1>${body}님 환영합니다.</h1>`);
});

express를 사용하여 html코드를 res.send를 브라우저에 응답할 때 템플릿 형태로 작성하는 경우가 많은데 이것은 라이브러리가 굉장히 많기 때문에 골라서 사용하면 될 듯

ajax 사용하기

// form.html 
/*  생략 */
document.querySelector(".ajaxsend").addEventListener("click", function() {
        const email = document.querySelector("#email_input").value;
        ajaxSend("http://localhost:3000/ajax_send_email", email);
      });

      function ajaxSend(url, email) {
        let data = { email };
        data = JSON.stringify(data);
        const xhr = new XMLHttpRequest();
        xhr.open("POST", url);
        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.send(data);
        xhr.addEventListener("load", function() {
          const res = JSON.parse(xhr.responseText);
          if (res.status != "ok") return;
          document.querySelector("#response_email").innerHTML = res.email;
        });
      }
// app.js
app.post("/ajax_send_email", function(req, res) {
  res.send({ status: "ok", email: req.body.email });
});

xhr에 대한 정리는 따로 필요할 듯