[Nodejs] 생활코딩 - Node.js 5

5 minute read

JavaScript - 객체 - 데이터와 값을 담는 그릇으로서 객체

다른 사람과 협업을 할 때, 이미 선언된 변수에 다른 값을 할당하는 문제가 발생할 수 있다.

var = v1;
v1 = going; // 다른사람이 추가한 코드
var v2 = v2; 

이럴 때 서로 연관된 데이터를 객체에 정리정돈해 놓고 사용하면 방지 할 수 있다.

var o = {
	v1 : v1,
	v2 : v2;
}

함수의 경우도 마찬가지, 객체의 프로퍼티로 함수를 사용할 수 있기때문에 서로 연관된 함수를 객체에 담아서 사용하면 코드가 훨씬 정리정돈 된다.

var o = {
	v1 : v1,
	v2 : v2,
	 f1 : function (){
		console.log(this.v1);
	} ,
	 f2 : function (){
		console.log(this.v2);
	} 
}

o.f1();
o.f2();

객체는 서로 연관된 데이터와 함수를 저장해서 코드의 복잡도를 낮추는 그릇이다.

App -객체를 이용해서 템플릿 기능 정리 정돈하기

var http = require('http');
var fs = require('fs');
var url = require('url');
var qs = require('querystring');

var template = {
    html : function (title,list,body,control){
        return    `<!doctype html>
                    <html>
                    <head>
                    <title>WEB1 - ${title}</title>
                    <meta charset="utf-8">
                    </head>
                    <body>
                    <h1><a href="/">WEB</a></h1>
                    ${list}
                    ${control}
                    ${body}
                    </body>
                    </html>
                `;
    },
    list : function(filelist){
        var list = '<ul>';
        var i =0;
        while( i < filelist.length){
            list = list + `<li><a href="/?id=${filelist[i]}">${filelist[i]}</a></li>`;
            i = i  +  1;
        }
        list = list + '</ul>';

        return list;
    }

}

var app = http.createServer(function(request,response){
    var _url = request.url;
    var queryData = url.parse(_url,true).query;
    var pathname = url.parse(_url,true).pathname
  
    console.log('queryData : ',queryData.id);
  
    if(pathname =='/'){
        if(queryData.id ===undefined){
           fs.readdir('./data', function(error,filelist){

            var title ='Welcome';
            var description = 'Hello, Nodejs';
            var list = template.list(filelist);
            var html = template.html(title,list,
                `<h2>${title}</h2><p>${description}</p>`,
                `<a href="/create">create</a> `);

            response.writeHead(200);
            response.end(html);
            })           
        }else{

            fs.readdir('./data', function(error,filelist){
            fs.readFile(`data/${queryData.id}`,'utf8',function(err,description){
                var title = queryData.id;
                var list = template.list(filelist);
                var html = template.html(title,list,
                    `<h2>${title}</h2><p>${description}</p>`,
                    `<a href="/create">create</a> 
                    <a href="/update?id=${title}">update</a>
                    <form action="delete_process" method="post">
                    <input type="hidden" name="id" value="${title}">
                    <input type="submit" value="delete">
                    </form>
                    `
                    );
                response.writeHead(200);
                response.end(html);
            })
          })
        }
    
    }else if(pathname=='/create'){
        fs.readdir('./data', function(error,filelist){
            var title ='WEB - create';
            var list = template.list(filelist);
            var html = template.html(title,list,`
                <form action="/create_process" method="post">
                    <p><input type="text" name="title" placeholder="title"></p>
                    <p>
                        <textarea name="description" placeholder="description"></textarea>
                    </p>
                    <p>
                        <input type="submit" name="submit">
                    </p>
                </form>`
            ,'');
            response.writeHead(200);
            response.end(html);
        })
    }else if(pathname=='/create_process'){
       var body  = '';
       request.on('data', function(data){
            body += data;

            //Too much POST data, kill the connection !
            // 1e6 === 1 * Math.pow(10,6) === 1 * 1000000 ~~~ 1MB
            /* 용량이 너무 크면 접속을 끊는 소스
            if(body.length > 1e6){
                request.connection.destroy();
            }
            */
       });
       request.on('end', function(){ // data가 조각조각 전송되다가 더 이상 전송될 데이터가 없으면 호출 됨.(callback함수) 정보수신이 끝났다고 볼 수 있음.
            var post = qs.parse(body);
            var title = post.title;
            var description = post.description;
            fs.writeFile(`data/${title}`,description,'utf8',(err) => {
                response.writeHead(302,{Location: `/?id=${title}`});
                response.end();
            })
       });
     
    }else if(pathname =='/update'){
        fs.readdir('./data', function(error,filelist){
            fs.readFile(`data/${queryData.id}`,'utf8',function(err,description){
                var title = queryData.id;
                var list = template.list(filelist);
                var html = template.html(title,list,
                    `
                    <form action="/update_process" method="post">
                        <input type="hidden" name="id" value="${title}">
                        <p><input type="text" name="title" placeholder="title" value="${title}"></p>
                        <p>
                            <textarea name="description" placeholder="description" >${description}</textarea>
                        </p>
                        <p>
                            <input type="submit" name="submit">
                        </p>
                     </form>
                    `,
                    `<a href="/create">create</a> <a href="/update?id=${title}">update</a>`
                    );
                response.writeHead(200);
                response.end(html);
            })
          })
        

    } else if(pathname =='/update_process'){
        var body  = '';
       request.on('data', function(data){
            body += data;

       });
       request.on('end', function(){ 
            var post = qs.parse(body);
            var title = post.title;
            var id = post.id;
            var description = post.description;
            console.log('post: ',post);
            fs.rename(`data/${id}`, `data/${title}`, function(err){
                fs.writeFile(`data/${title}`,description,'utf8',(err) => {
                    response.writeHead(302,{Location: `/?id=${title}`});
                    response.end();
                })
            })
       });
    } else if(pathname =='/delete_process'){
        var body  = '';
       request.on('data', function(data){
            body += data;

       });
       request.on('end', function(){ 
            var post = qs.parse(body);
            var id = post.id;
            fs.unlink(`data/${id}`,(err) => {
                //삭제가 끝나면 홈으로
                response.writeHead(302,{Location: `/`});
                response.end();
            })
       });
    }else{
        response.writeHead(404);
        response.end('Not Found');
    }
});
app.listen(3000);

App 제작 - 모듈의 활용

모듈을 활용해서 템플릿 기능을 모듈화 pm2는 main.js 가 require 하고 있는 모듈의 변화도 감지해서, 변경이 일어났을때 프로세스를 껐다가 다시 켜주는 것을 마찬가지로 해준다.

App - 입력 정보에 대한 보안

path 모듈은 파일과 Directory 경로 작업을 위한 Utility를 제공한다.

const path = require('path');

path.parse()는 문자열로 전달된 path경로를 객체로 반환해준다.

path.parse('/home/user/dir/file.txt');
// Returns:
// { root: '/',
//   dir: '/home/user/dir',
//   base: 'file.txt',
//   ext: '.txt',
//   name: 'file' }

main.js

var http = require('http');
var fs = require('fs');
var url = require('url');
var qs = require('querystring');
var template = require('./lib/template');
var path = require('path');

var app = http.createServer(function(request,response){
    var _url = request.url;
    var queryData = url.parse(_url,true).query;
    var pathname = url.parse(_url,true).pathname
  
    console.log('queryData : ',queryData.id);
  
    if(pathname =='/'){
        if(queryData.id ===undefined){
           fs.readdir('./data', function(error,filelist){

            var title ='Welcome';
            var description = 'Hello, Nodejs';
            var list = template.list(filelist);
            var html = template.html(title,list,
                `<h2>${title}</h2><p>${description}</p>`,
                `<a href="/create">create</a> `);

            response.writeHead(200);
            response.end(html);
            })           
        }else{

            fs.readdir('./data', function(error,filelist){
                var filteredId = path.parse(queryData.id).base;
                fs.readFile(`data/${filteredId}`,'utf8',function(err,description){
                var title = queryData.id;
                var list = template.list(filelist);
                var html = template.html(title,list,
                    `<h2>${title}</h2><p>${description}</p>`,
                    `<a href="/create">create</a> 
                    <a href="/update?id=${title}">update</a>
                    <form action="delete_process" method="post">
                    <input type="hidden" name="id" value="${title}">
                    <input type="submit" value="delete">
                    </form>
                    `
                    );
                response.writeHead(200);
                response.end(html);
            })
          })
        }
    
    }else if(pathname=='/create'){
        fs.readdir('./data', function(error,filelist){
            var title ='WEB - create';
            var list = template.list(filelist);
            var html = template.html(title,list,`
                <form action="/create_process" method="post">
                    <p><input type="text" name="title" placeholder="title"></p>
                    <p>
                        <textarea name="description" placeholder="description"></textarea>
                    </p>
                    <p>
                        <input type="submit" name="submit">
                    </p>
                </form>`
            ,'');
            response.writeHead(200);
            response.end(html);
        })
    }else if(pathname=='/create_process'){
       var body  = '';
       request.on('data', function(data){
            body += data;

            //Too much POST data, kill the connection !
            // 1e6 === 1 * Math.pow(10,6) === 1 * 1000000 ~~~ 1MB
            /* 용량이 너무 크면 접속을 끊는 소스
            if(body.length > 1e6){
                request.connection.destroy();
            }
            */
       });
       request.on('end', function(){ // data가 조각조각 전송되다가 더 이상 전송될 데이터가 없으면 호출 됨.(callback함수) 정보수신이 끝났다고 볼 수 있음.
            var post = qs.parse(body);
            var title = post.title;
            var description = post.description;
            fs.writeFile(`data/${title}`,description,'utf8',(err) => {
                response.writeHead(302,{Location: `/?id=${title}`});
                response.end();
            })
       });
     
    }else if(pathname =='/update'){
        fs.readdir('./data', function(error,filelist){
            var filteredId = path.parse(queryData.id).base;
            fs.readFile(`data/${filteredId}`,'utf8',function(err,description){
                var title = queryData.id;
                var list = template.list(filelist);
                var html = template.html(title,list,
                    `
                    <form action="/update_process" method="post">
                        <input type="hidden" name="id" value="${title}">
                        <p><input type="text" name="title" placeholder="title" value="${title}"></p>
                        <p>
                            <textarea name="description" placeholder="description" >${description}</textarea>
                        </p>
                        <p>
                            <input type="submit" name="submit">
                        </p>
                     </form>
                    `,
                    `<a href="/create">create</a> <a href="/update?id=${title}">update</a>`
                    );
                response.writeHead(200);
                response.end(html);
            })
          })
        

    } else if(pathname =='/update_process'){
        var body  = '';
       request.on('data', function(data){
            body += data;

       });
       request.on('end', function(){ 
            var post = qs.parse(body);
            var title = post.title;
            var id = post.id;
            var filteredId = path.parse(id).base;
            var description = post.description;
            console.log('post: ',post);
            fs.rename(`data/${filteredId}`, `data/${title}`, function(err){
                fs.writeFile(`data/${title}`,description,'utf8',(err) => {
                    response.writeHead(302,{Location: `/?id=${title}`});
                    response.end();
                })
            })
       });
    } else if(pathname =='/delete_process'){
        var body  = '';
       request.on('data', function(data){
            body += data;

       });
       request.on('end', function(){ 
            var post = qs.parse(body);
            var id = post.id;
            var filteredId = path.parse(id).base;
            fs.unlink(`data/${filteredId}`,(err) => {
                //삭제가 끝나면 홈으로
                response.writeHead(302,{Location: `/`});
                response.end();
            })
       });
    }else{
        response.writeHead(404);
        response.end('Not Found');
    }
});
app.listen(3000);

Leave a comment