2023-01-31 node.js_8

2023. 1. 31. 02:04공부 중/Node.js


 

WEB2 - Node.js - 생활코딩

수업소개 이 수업은 JavaScript를 이용해서 Node.js를 제어해 동적으로 HTML 코드를 생성하는 웹애플리케이션을 만드는 방법에 대한 수업입니다.  수업대상 예를들어 1억개의 페이지로 이루어진 웹사

opentutorials.org

생활코딩 node.js 강의 정리

 


1. Not found 구현

 

기존에 코드를 개선할 거다.

 

대상 코드는 url의 분석해서 존재하는 페이지인지 혹은 존재하지 않는 페이지인지 판단하는 코드다.

 

// 수정할 부분
...
if(_url == '/'){
    title = 'Welcome';
}
if(_url == '/favicon.ico'){
    response.writeHead(404);
    response.end();
    return;
}
...
response.writeHead(200);
...

우리가 고려해야 할 경우의 수는 3가지다.

 

 

var pathname = url.parse(_url, true).pathname;

if(pathname === '/') {
    if(queryData.id === undefined) {
        // 1번 case
    }else{
        // 2번 case
    }
}else{
    // 3번 case
}
  • var pathname = url.parse(_url, true).pathname;
    : url 정보 중 경로(path)에 관한 정보만 추출해 저장한다.

 

이제 각각의 case일 때 어떻게 동작해야 하는지 생각해 보자.

 


가. 1번 case

 

1번 case의 경우 root 페이지를 보여주면 된다.

var title = 'Welcome';
var description = 'Hello Node.js';
var template = ` ... `;
response.writeHead(200);
response.end(template);

 


나. 2번 case

 

2번 case의 경우에는 쿼리스트링에 맞게 파일을 읽어와서 본문을 구성하면 된다.

fs.readFile(`data/${queryData.id}`, 'utf-8', function(err, description){
    var title = queryData.id;
    var template = ` ... `;
    response.writeHead(200);
    response.end(template);
});

 


다. 3번 case

 

3번 case는 존재하지 않는 페이지라고 알려주면 된다.

 

 

주소를 잘못 입력한 경우 자주 겪어봤을 것이다.

 

우리도 똑같이 하면 된다.

앞서 response.writeHead(200);라는 코드를 많이 봤을 것이다.

 

해당 코드의 숫자가 바로 HTTP 응답 코드다.

 

200은 파일이 성공적으로 전송되었음을 나타낸다.

 

404 코드로 응답하면 Not Found 즉 요청한 파일이 없다는 뜻이다.

 

response.writeHead(404);
response.end('Not found');

 


라. 합치기

 

엑조디아

를 완성해 보자.

var http = require("http");
var fs = require("fs");
var url = require("url");

var app = http.createServer(function (request, response) {
  var _url = request.url;
  console.log(_url);
  var queryData = url.parse(_url, true).query;
  var pathname = url.parse(_url, true).pathname;

  if (_url == "/style.css") {
    response.writeHead(200, { "Content-type": "text/css" });
    var fileContents = fs.readFileSync("style.css", "utf-8");
        response.write(fileContents);
    response.end();
  }

  if (_url == "/color.js") {
    response.writeHead(200, { "Content-type": "text/js" });
    var fileContents = fs.readFileSync("color.js", "utf-8");
        response.write(fileContents);
    response.end();
  }

  if (pathname === "/") {
    if (queryData.id === undefined) {
      var title = "Welcome";
      var description = "Hello Node.js";
      var template = `
          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta http-equiv="X-UA-Compatible" content="IE=edge" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>WEB - ${title}</title>
              <link rel="stylesheet" href="style.css">
              <script src="color.js"></script>
            </head>
            <body>
              <div id="top">
                <h1><a href="/">차</a></h1>
                <input type="button" value="night" onclick="nightDayHandler(this)"/>
              </div>
              <div id="grid">
                <ul>
                  <li><a href="/?id=black%20tea">홍차</a></li>
                  <li><a href="/?id=oolang%20tea">우롱차</a></li>
                  <li><a href="/?id=green%20tea">녹차</a></li>
                </ul>
                <div id="article">${description}</div>
              </div>
            </body>
          </html>
        `;

      response.writeHead(200);
      response.end(template);
    } else {
      fs.readFile(`data/${queryData.id}`, "utf-8", function (err, description) {
        var title = queryData.id;
        var template = `
              <!DOCTYPE html>
              <html lang="en">
                <head>
                  <meta charset="UTF-8" />
                  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                  <title>WEB - ${title}</title>
                  <link rel="stylesheet" href="style.css">
                  <script src="color.js"></script>
                </head>
                <body>
                  <div id="top">
                    <h1><a href="/">차</a></h1>
                    <input type="button" value="night" onclick="nightDayHandler(this)"/>
                  </div>
                  <div id="grid">
                    <ul>
                      <li><a href="/?id=black%20tea">홍차</a></li>
                      <li><a href="/?id=oolang%20tea">우롱차</a></li>
                      <li><a href="/?id=green%20tea">녹차</a></li>
                    </ul>
                    <div id="article">${description}</div>
                  </div>
                </body>
              </html>
            `;
        response.writeHead(200);
        response.end(template);
      });
    }
  } else {
    response.writeHead(404);
    response.end("Not found");
  }
});
app.listen(3000);

이렇게 하면 망한다.

 

왜냐 …

 

 if (_url == "/style.css") {
    response.writeHead(200, { "Content-type": "text/css" });
    var fileContents = fs.readFileSync("style.css", "utf-8");
        response.write(fileContents);
    response.end();
  }

  if (_url == "/color.js") {
    response.writeHead(200, { "Content-type": "text/js" });
    var fileContents = fs.readFileSync("color.js", "utf-8");
        response.write(fileContents);
    response.end();
  }

이 부분과 …

    } else {
    response.writeHead(404);
    response.end("Not found");
  }
});

이 부분 때문이다.

 

우리가 style.css와 color.js를 가져오면서 한번 response.end()를 실행한다.

 

문제는 style.css와 color.js는 우리가 분류한 3번 case에 포함된다.

 

이에 response.end()가 2번 실행되며 Error [ERR_STREAM_WRITE_AFTER_END]: write after end와 같은 오류가 발행한다.

 

해결하기 위해서 3번 case를 아래와 같이 수정한다.

 

} else {
    if (_url == "/style.css") {
      response.writeHead(200, { "Content-type": "text/css" });
      var fileContents = fs.readFileSync("style.css", "utf-8");
      response.write(fileContents);
      response.end();
    } else if (_url == "/color.js") {
      response.writeHead(200, { "Content-type": "text/js" });
      var fileContents = fs.readFileSync("color.js", "utf-8");
      response.write(fileContents);
      response.end();
    } else {
      response.writeHead(404);
      response.end("Not found");
    }
  }

최종적으로 아래와 같이 된다.

 

var http = require("http");
var fs = require("fs");
var url = require("url");

var app = http.createServer(function (request, response) {
  var _url = request.url;
  console.log(_url);
  var queryData = url.parse(_url, true).query;
  var pathname = url.parse(_url, true).pathname;

  if (pathname === "/") {
    if (queryData.id === undefined) {
      var title = "Welcome";
      var description = "Hello Node.js";
      var template = `
          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta http-equiv="X-UA-Compatible" content="IE=edge" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>WEB - ${title}</title>
              <link rel="stylesheet" href="style.css">
              <script src="color.js"></script>
            </head>
            <body>
              <div id="top">
                <h1><a href="/">차</a></h1>
                <input type="button" value="night" onclick="nightDayHandler(this)"/>
              </div>
              <div id="grid">
                <ul>
                  <li><a href="/?id=black%20tea">홍차</a></li>
                  <li><a href="/?id=oolang%20tea">우롱차</a></li>
                  <li><a href="/?id=green%20tea">녹차</a></li>
                </ul>
                <div id="article">${description}</div>
              </div>
            </body>
          </html>
        `;
      response.writeHead(200);
      response.end(template);
    } else {
      fs.readFile(`data/${queryData.id}`, "utf-8", function (err, description) {
        var title = queryData.id;
        var template = `
              <!DOCTYPE html>
              <html lang="en">
                <head>
                  <meta charset="UTF-8" />
                  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                  <title>WEB - ${title}</title>
                  <link rel="stylesheet" href="style.css">
                  <script src="color.js"></script>
                </head>
                <body>
                  <div id="top">
                    <h1><a href="/">차</a></h1>
                    <input type="button" value="night" onclick="nightDayHandler(this)"/>
                  </div>
                  <div id="grid">
                    <ul>
                      <li><a href="/?id=black%20tea">홍차</a></li>
                      <li><a href="/?id=oolang%20tea">우롱차</a></li>
                      <li><a href="/?id=green%20tea">녹차</a></li>
                    </ul>
                    <div id="article">${description}</div>
                  </div>
                </body>
              </html>
            `;
        response.writeHead(200);
        response.end(template);
      });
    }
  } else {
    if (_url == "/style.css") {
      response.writeHead(200, { "Content-type": "text/css" });
      var fileContents = fs.readFileSync("style.css", "utf-8");
      response.write(fileContents);
      response.end();
    } else if (_url == "/color.js") {
      response.writeHead(200, { "Content-type": "text/js" });
      var fileContents = fs.readFileSync("color.js", "utf-8");
      response.write(fileContents);
      response.end();
    } else {
      response.writeHead(404);
      response.end("Not found");
    }
  }
});
app.listen(3000);

 


'공부 중 > Node.js' 카테고리의 다른 글

2023-02-11 node.js_10  (0) 2023.02.11
2023-02-11 node.js_9  (0) 2023.02.11
2023-01-30 node.js_7  (0) 2023.01.30
2023-01-23 node.js_6  (0) 2023.01.23
2023-01-23 node.js_5  (0) 2023.01.23