Node.js | Node.js 스크립트 기본 | HTML 파일 표시


그러면 실제로 HTML 파일을 읽어 들여 표시시켜 보기로 하자.

HTML파일을 읽어서 표시하기

먼저 로드 HTML 파일을 작성해야 한다. 여기에서는 “hello.html"이라는 파일명으로 만들어 보자. 아래 샘플 코드를 올려 두었다. 내용은 어떤 것이라도 전혀 상관 없다. 작성한 파일은 Node.js 스크립트 파일 (앞에서 만든 sampleapp.js)와 같은 위치에 배치해야 한다.

hello.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>sample</title>
    <style>
    body { font-size:12pt; color:#006666; }
    h1 { font-size:18pt; background-color:#AAFFFF; }
    pre { background-color:#EEEEEE; }
    </style>
</head>

<body>
    <header>
        <h1 id="h1">Sample Page</h1>
    </header>
    <div role="main">
        <p>이것은 Node.js 예제입니다.</p>
    </div>
</body>
 
</html>

이어서 스크립트를 작성한다. 이것도 아래에 예제를 올려 두었다. 스크립트를 작성한 후 명령 줄에서 “node sampleapp.js"를 실행하고 브라우저에서 액세스해 보자.

sampleapp.js

var http = require('http');
var fs = require('fs');

var server = http.createServer();
server.on('request', doRequest);
server.listen(1234);
console.log('Server running!');

// 요청 처리
function doRequest(req, res) {
   fs.readFile('./hello.html', 'UTF-8', 
       function(err, data) {
           res.writeHead(200, {'Content-Type': 'text/html'});
           res.write(data);
           res.end();
       });
}

hello.html 파일 내용의 페이지가 표시될 것이다.

여기에서는 요청시에 실행되는 doRequest 함수에서 hello.html을 로드하고 표시하는 처리를 하고 있다. 이 doRequest에서 로드 처리는 정리하면 다음과 같이 되어 있다.

fs.readFile('./hello.html', 'UTF-8', 
    function(err, data) {
            ... 읽기 완료 후에 처리 ...
    });

첫번째 인수에 “./hello.html"라고 파일 경로를 지정하고, 두번째 인수는 ‘UTF-8’을 지정한다. 그리고 세번재 인수에 읽기 완료 후에 처리를 할 콜백 함수가 준비되어 있다. 이 콜백 함수는 두 개의 인수가 준비되어 있다. 첫번째 인수는 오류가 발생한 경우 오류 메시지이다. 로드에 실패했을 경우의 처리를 준비한다면, 함수에서 if (err) {...}와 같은 형태로 적어 놓으면 좋을 것이다.

두번째 인수의 data에는 가져온 텍스트가 저장되어 있다. 이를 response의 write로 내내기 위하여 것이다. readFile의 콜백 함수의 처리를 보면,

res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
res.end();

이와 같이 writeHead, write, end이 이 안에서 실행되고 있다. 이것은 중요하다. 예를 들어, 이 doRequest의 처리는, 아래와 같이 쓰고 싶을지도 모른다.

function doRequest(req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    fs.readFile('./hello.html', 'UTF-8', 
        function(err, data) {
            res.write(data);
        });
    res.end();
}

읽어 들인 데이터를 출력하는 write만 readFile의 콜백 함수에 준비하면 된다고 생각할 있다. 하지만 이것으로는 동작하지 않는다. “readFile는 비동기이다"라는 점을 잊어서는 안된다. readFile 콜백 함수를 호출 이전에 다음의 res.end 실행되어 버릴 것이다. 콜백 함수의 res.write을 실행할 때는 이미 요청 처리가 완료되어 버릴 것이다.

이렇게 비동기적으로 수행하는 처리가 포함되어 있을 때에는 “비동기 작업이 완료한 후에 응답 처리를 한다"는 점에 주의해야 한다.

HTML의 일부를 스크립트로 변경

단지, HTML 파일을 읽어 들여 표시하는 것만으로는 그다지 서버 사이드 프로그램을 만드는 장점이 느껴지지 않는다. 거기서 읽어들인 HTML을 기초로 하여 작은 텍스트 처리를 실시하도록 하자.

템플릿적인 개념이 먼저 표시되는 HTML에서, 텍스트를 대체하기 위한 특별한 값를 넣어, 그것을 로드하고 표시하는데 필요한 내용으로 대체하여 출력하는 방법을 생각할 수 있다. 해보도록 하자.

먼저 hello.html을 수정한다.

hello.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>@title@</title>
    <style>
    body { font-size:12pt; color:#006666; }
    h1 { font-size:18pt; background-color:#AAFFFF; }
    pre { background-color:#EEEEEE; }
    </style>
</head>
  
<body>
    <header>
        <h1 id="h1">@title@</h1>
    </header>
    <div role="main">
        <p>@content@</p>
    </div>
</body>
 
</html>

기본적으로 앞전과 거의 동일하지만, 소스 코드 안에 “@title@“와 “@content@“라는 것이 작성이 있는 것을 보일 것이다. 이것이 대체용 특수값이다(별도로 Node.js에 그러한 특별한 값이 정의되고 있을 일이 없다. 적당히 생각한 값이다). 스크립트에는 이러한 텍스트를 검색하고 대체하여, 스크립트로 HTML 내에서 연산할 수 있을 것이다.

Node.js의 스크립트를 아래에 올려 둡니다.

sampleapp.js

var http = require('http');
var fs = require('fs');
 
var server = http.createServer();
server.on('request', doRequest);
server.listen(1234);
console.log('Server running!');
 
// 요청 처리
function doRequest(req, res) {
    var number = Math.floor(Math.random() * 3);
    fs.readFile('./hello.html', 'UTF-8', 
        function(err, data) {
            var title = ["페이지A", "페이지B", "페이지C"];
            var content = ["이것은 예제로 만든 것입니다.",
                "또 하나의 컨텐츠입니다.",
                "최후에 이용한 컨텐츠입니다."];
            var data2 = data.
                replace(/@title@/g, title[number]).
                replace(/@content@/g, content[number]);
            res.writeHead(200, {'Content-Type': 'text/html'});
            res.write(data2);
            res.end();
        });
}

여기에는 텍스트를 읽은 후에 replace에서 텍스트 바꾸기를 하고 있다.

var data2 = data.replace(/@title@/g, title[number]).
        replace(/@content@/g, content[number]);

이렇게 하여 @title@와 @content@를 각각 배열 title/content에서 무작위로 선택한 것으로 대체하고 write하고 있다. 페이지를 새로 고침할 때마다, 랜덤으로 선택된 텍스트가 표시되는걸 확인할 수 있을 것이다.

또한, 여기에서는 비동기적으로 파일을 로드하는 readFile를 사용했는데, 동기화 처리에 파일을 읽어들이는 메소드도 fs에 포함되어 있다. 이것에 대해서는 다음에 다시 접하게 될 것이다.

우선, 여기에는 적은 값을 스크립트에서 HTML 내에 포함 할 수 있었다. 그러나 이것으로는 너무 융통성은 없다. 좀 더 범용적으로 표시를 생성하고 조작할 수 없으면 곤란하다. 그럼 다음은 “템플릿 엔진"이라는 것을 사용하여 좀 더 편리하게 HTML을 사용할 수 있도록 해보자.