웹 풀스택

쇼핑몰 만들기 - HTML, Node.js, MariaDB 연결

kevinmj12 2025. 2. 5. 16:42

Node.js와 MariaDB를 연결하였으니 이젠 HTML과 Node.js를 연결하여보자.

연결하는 방법은 간단한데, 다음 코드 두 줄만 추가해주면 된다.

 

HTML - Node.js 연결

const fs = require("fs");
const main_view = fs.readFileSync("./main.html", "utf-8");

 

이후 main.html을 보여주고 싶은 곳에서 console.write(main_view)를 통해 세팅을 해주면 된다.

 

function main(response) {
  mariadb.query("SELECT * FROM product", function (err, rows) {
    console.log(rows);
  });

  response.writeHead(200, { "Content-Type": "text/html" });
  response.write(main_view);
  response.end();
}

 

이후 서버를 실행시켜 main.html을 확인해보면 한 가지 문제가 발생한다.

 

기존에는 잘 나오던 이미지가 잘 나오지 않는다.

그 이유는 이미지가 pathname으로 전달되는데 requestHandler.js에서 이를 처리해주지 못하고 있기 때문이다.

handle에 key, value를 추가해주고 각 이미지에 맞게 함수를 생성하여 주자.

// requestHandler.js

const fs = require("fs");
const main_view = fs.readFileSync("./main.html", "utf-8");
const mariadb = require("./database/connect/mariadb");

function main(response) {
  mariadb.query("SELECT * FROM product", function (err, rows) {
    console.log(rows);
  });

  response.writeHead(200, { "Content-Type": "text/html" });
  response.write(main_view);
  response.end();
}

function redRacket(response) {
  // 이미지 파일을 읽어오는 것은 fs.readFile임에 주의
  fs.readFile("./img/redRacket.png", function (err, data) {
    response.writeHead(200, { "Content-Type": "text/html" });
    response.write(data);
    response.end();
  });
}

function blueRacket(response) {
  fs.readFile("./img/blueRacket.png", function (err, data) {
    response.writeHead(200, { "Content-Type": "text/html" });
    response.write(data);
    response.end();
  });
}

function blackRacket(response) {
  fs.readFile("./img/blackRacket.png", function (err, data) {
    response.writeHead(200, { "Content-Type": "text/html" });
    response.write(data);
    response.end();
  });
}

let handle = {};
handle["/"] = main;

// image directory
handle["/img/redRacket.png"] = redRacket;
handle["/img/blueRacket.png"] = blueRacket;
handle["/img/blackRacket.png"] = blackRacket;

exports.handle = handle;

 

 

HTML - Node.js - MariaDB 연결

이어서 order 버튼을 누르면 데이터베이스의 orderlist 테이블에 항목을 추가하도록 해보자.

먼저 mariadb에서 orderlist 테이블을 만들어준다.

 

order 버튼을 누르면 product_id와 날짜를 전달해주어야 한다.

날짜는 Node.js에서 제공하는 함수를 통해 해결이 가능하지만, product_id는 main.html에서부터 차근차근 전달해주어야 한다.

차근차근 product_id를 전달하여보자.

 

<!-- main.html -->

<input
  class="card_button"
  type="button"
  value="order"
  onclick="location.href='/order?productId=1'"
/>

 

main.html에서 버튼에 해당되는 태그에서 onclick을 다음과 같이 설정해준다.

이제 저 버튼을 클릭하면, /order?productId=1 페이지로 이동하게 될 것이다.

 

// 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;
    let queryData = url.parse(request.url, true).query;

    route(pathname, handle, response, queryData.productId);
  }

  http.createServer(onRequest).listen(8888);
}

exports.start = start;

 

다음은 server.js를 수정해주어야 한다.

기존에는 pathname만을 전달해주었었는데, 이제는 productId도 같이 전달해주어야 하는 상황이 생겼다.

queryData 변수에 그 값을 저장하여 라우터에 전달해주도록 하자.

 

// router.js

function route(pathname, handle, response, productId) {
  if (typeof handle[pathname] == "function") {
    handle[pathname](response, productId);
  } else {
    response.writeHead(404, { "Content-Type": "text/html" });
    response.write("This page could not be found");
    response.end();
  }
}

exports.route = route;

 

router.js에서는 server.js로부터 전달받은 productId를 requestHanlder.js의 handle에 포함시켜 전달해준다.

 

// requestHandler.js

function order(response, productId) {
  response.writeHead(200, { "Content-Type": "text/html" });

  mariadb.query(
    `INSERT INTO orderlist VALUES (${productId}, '${new Date().toLocaleDateString()}');`,
    function (err, rows) {
      console.log(rows);
    }
  );

  response.write("order page");
  response.end();
}

handle["/order"] = order;

 

대망의 requestHandler.js이다.

order() 함수를 새로 만들어 response와 product를 전달받는다.

그리고 mariadb의 orderlist 테이블에 INSERT INTO 명령을 실행하면 된다.

VALUES에는 기존에 전달받았던 productId와 현재 날짜를 입력해준다.

현재 날짜는 new Date().toLocaleDateString() 함수를 통해 편리하게 받아올 수 있다.

 

위 작업을 모두 마친 후, 1번 품목의 order 버튼을 누르고 orderlist 테이블을 확인해보면?

 

처음에는 없었던 orderlist들이 생겨난 것을 볼 수 있다!

 

MariaDB - Node.js - HTML 연결

이제 거꾸로, mariadb의 데이터를 불러와 웹페이지에 띄워보도록 하자.

목표는 orderlist 테이블로부터 데이터를 불러와 orderlist 페이지에 보여주는 것이다.

 

// requestHandler.js

const orderlist_view = fs.readFileSync("./orderlist.html", "utf-8");

function orderlist(response) {
    response.writeHead(200, { "Content-Type": "text/html" });
    response.write(orderlist_view);
    response.end();
  });
}

handle["/orderlist"] = orderlist;

 

가장 먼저 해야할 일은 handle에 orderlist를 추가해준 뒤 orderlist.html을 연결하는 것이다.

이제 /orderlist에 접속하면 orderlist.html에 해당되는 페이지가 잘 보일 것이다.

그런데 아직 orderlist 테이블에 있는 값을 불러온 것은 아니다.

 

// requestHandler.js

const orderlist_view = fs.readFileSync("./orderlist.html", "utf-8");

function orderlist(response) {
  mariadb.query(`SELECT * FROM orderlist`, function (err, rows) {
    response.writeHead(200, { "Content-Type": "text/html" });
    response.write(orderlist_view);

    rows.forEach((element) => {
      response.write(`<tr>
        <td>${element.product_id}</td>
        <td>${element.order_date}</td>
        </tr>
        `);
    });

    response.write(`</table>`);

    response.end();
  });
}

handle["/orderlist"] = orderlist;

 

mariadb.query로 SELECT문을 실행하여 rows에 orderlist에 해당하는 값을 rows 받아왔다.

그리고 rows를 출력해보면 다음과 같다.

[
  RowDataPacket { product_id: 1, order_date: '2025. 2. 5.' },
  RowDataPacket { product_id: 1, order_date: '2025. 2. 5.' },
  RowDataPacket { product_id: 1, order_date: '2025. 2. 5.' }
]

이제 이 친구들을 보여줘야 하는데, rows.forEach()를 통해 각 데이터를 write해줄 것이다.

 

이 때 각각 항목들은 html의 <table> 태그에 추가되어야 하므로 각 데이터를 

 

<tr>
    <td>${element.product_id}</td>
    <td>${element.order_date}</td>
</tr>

 

과 같이 감싸 추가해주었다.

그리고 마지막으로 테이블이 끝났다는 뜻인 </table>을 write해주었다.

 

이대로 작성을 완료하고 웹페이지를 확인해보면?

 

 

orderlist 테이블 값은 잘 나왔지만 테이블에 들어가지 않았다.

orderlist.html에 <talbe> 태그를 수정하지 않았기 때문이다.

 

<!-- orderlist.html -->

<!DOCTYPE html>

<html>
  <head>
    <meta charset="UTF-8" />
    <title>Order List</title>
    <style>
      h1 {
        text-align: center;
      }
      table {
        margin-left: auto;
        margin-right: auto;
      }
      th,
      td {
        padding: 10px;
      }
      div {
        text-align: center;
        margin-bottom: 50px;
      }
    </style>
  </head>
  <body>
    <h1>Order List</h1>
    <div>
      <a href="/">GO Home</a>
    </div>

    <table style="border: 1px solid black">
      <tr>
        <th>Product ID</th>
        <th>Order date</th>
      </tr>
    <!-- </table>  이 부분 주석처리! -->
  </body>
</html>

 

기존 orderlist.html의 마지막 </table> 태그를 지우거나 주석처리해준다면?

 

 

기대했던 화면이 잘 나오는 모습이다!