본문 바로가기

Web Development/Back-end

[생활코딩-Nodejs-18] '사용자 게시판 - 삭제기능' 만들기

이제 우리는 정보를 다루는 기본인,

Create

Read

Update

Delete

기능중에 Create, Read, Update를 할 수 있게 됐습니다.

 

마지막으로 살펴볼 부분은 Delete 삭제부분을 구현하는 방법에 대해 살펴보겠습니다.

 

 

여기도 마찬가지로 우선 UI를 만들어야겠죠?

 

1. User Interface구현

어떻게하면될까요?

template로 가서 update버튼 옆에 그냥 추가해주면 되겠죠?

 

그럼.. 안되요.

 

왜냐하면, 우린 지금 정보를 어떤 이유에서든 없애고자 하는 것이란말이에요?

그런데 Querystring이 존재하는 방식으로 Delete를 구현하게 되면 이 정보가 노출될 수 있고,

크래커의 위협이 존재하게됩니다.

따라서 우리는 이를 form태그를 이용해 POST방식으로 구현할 것입니다.

 

 

이렇게요.

form태그를 통해 delete_process라는 정보를 보낼 곳을 설정하고,

method를 POST로 설정해주며,

onsubmit이라는 자바스크립트의 문법을 통해 정말 삭제하시겠습니까?라는 경고창을 띄워주었습니다.

 

그리고나서,

input type hidden으로 처리했는데요.

어차피 사용자는 지울 것이기 때문에 해당 정보가 필요없습니다. 내부적으로 처리해주면 되는 것이죠.

따라서 이 부분에서 name값은 id로 주고,

value값을 ${title} 변수로 주어 정보를 선택했습니다.

 

그리고,

input type "submit" 버튼을 구현했구요.

value값을 Delete라고 주어 Delete 버튼을 생성 했습니다.

 

그럼 이렇게,

 

버튼이 생성된 화면을 볼 수 있고,

 

 

버튼을 눌르면, 쿼리스트링 값이 없는 POST 방식으로, delete_process로 이동하는 것을 확인할 수 있습니다.

 

 

2. 웹사이트 완성

update _ process 부분에서 실행했던 코드를 그대로 가져왔습니다.

그리고, 변수 id값을 할당해주고,

fs.unlink라는 nodejs의 기능을 통해 파일을 삭제하는 부분을 만들었습니다.

그리고, response.writeHead부분에서 페이지를 홈페이지로 갈 수 있도록 경로를 변경해주었습니다.

 

이제 , 홈페이지에서 원하는 글을 누르고, 삭제버튼을 클릭하면

글이 삭제되는 것을 확인할 수 있습니다.

 

이제 fs.unlink에 대해 살펴보겠습니다.

 

fs.unlink는 되게 단순하게 생겼어요.

fs.unlink(삭제할파일, callback) 으로 되어있습니다.

 

 

P.S : onsubmit은 설정했는데... 반응이 없네요... -_-ㅠ;

 

 

완성된 코드입니다.

 

var http = require('http'); // http 모듈
var fs = require('fs'); // filesystem 모듈
var url = require('url'); // URL 모듈
var qs = require('querystring'); //querystring 모듈

//template 내용 HTML 뼈대를 함수로 만들기.
function templateHTML(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>
  `;
}

//리스트를 자동으로 만들어주는 코드를 함수로 만들기.
function templateList(filelist){
  var list = '<ul>';
  var i = 0;
  while(i < filelist.length){
    list = list + `<li><a href="/?id=${filelist[i]}">${filelist[i]}</a></li>`;
    i+=1;
  }
  list = list +'</ul>';
  return list;
}

var app = http.createServer(function(request,response){
    var _url = request.url; //URL 요청
    var queryData = url.parse(_url, true).query; //URL을 분석하는 모듈 중, querystring 값
    var pathname = url.parse(_url, true).pathname; // URL을 분석하는 모듈 중, pathname 값
    //요청한 pathname이 루트값이라면 , if문이 실행
    if(pathname === '/'){ //Pathname이 루트 값일 경우 실행되는 코드
      if(queryData.id === undefined){
          //디렉토리를 읽는 함수 filelist변수가 파일목록. 배열로 반환.
          fs.readdir('./data', function(err, filelist){
            var title = 'Welcome';
            var description = 'Hello, Node.js';
            var list = templateList(filelist); //파일목록배열을 list변수에 할당.
            //HTML 뼈대 함수를 호출해 template 변수에 할당.
            var template = templateHTML(title, list, 
              `<h2>${title}</h2>${description}`,
              `<a href="/create">Create</a>`
              );
            response.writeHead(200); // 페이지가 정상적으로 출력되면 200, 오류페이지면 404.
            response.end(template); //화면출력하는부분에 template변수를 넣어줘서 출력.
          });

      //요청한 pathname이 루트값이 아니라면,대신 queryData.id가 있다면, else문 실행.
      } else {
        //디렉토리를 읽는 함수 filelist변수가 파일목록. 배열로 반환.
        fs.readdir('./data', function(err, filelist){
        //파일을 읽는 함수. description변수가 파일.
          fs.readFile(`data/${queryData.id}`, 'utf-8', function(err, description){
            var title = queryData.id
            var list = templateList(filelist);
            var template = templateHTML(title, list, 
              `<h2>${title}</h2>${description}`,
              `<a href="/create">Create</a> 
              <a href="/update?id=${title}">Update</a>
              <form action="delete_process" method="POST" onsubmit="삭제하시겠습니까?">
                <input type="hidden" name="id" value="${title}">
                <input type="submit" value="Delete">
              </form>
              `
              );
            response.writeHead(200); // 페이지가 정상적으로 출력되면 200, 오류페이지면 404.
            response.end(template); //화면출력하는부분
          });
        });
      };

    //pathName이 Create라면 실행할 조건문. 생성기능을 할 때 실행될 조건문. 데이터를 보내자!
    } else if(pathname ==='/create'){
          //디렉토리를 읽는 함수 filelist변수가 파일목록. 배열로 반환.
          fs.readdir('./data', function(err, filelist){
            var title = 'WEB - Create';
            var list = templateList(filelist); //파일목록배열을 list변수에 할당.
            //HTML 뼈대 함수를 호출해 template 변수에 할당.
            var template = templateHTML(title, list, `
            <!--form 태그-->
            <form action="http://localhost:3000/create_process" method="POST">
              <p><input type="text" name="title" placeholder="제목입력"></p>
              <p><textarea name="description" placeholder="본문입력"></textarea></p>
              <p><input type="submit"></p>
            </form> 
            `, '');
            response.writeHead(200); // 페이지가 정상적으로 출력되면 200, 오류페이지면 404.
            response.end(template); //화면출력하는부분에 template변수를 넣어줘서 출력.
          });

    //글쓰기를 실행했을 때 데이터를 받아온 데이터를 처리하는 조건문.
    } else if(pathname === '/create_process'){
      var body=''; // body에 빈 변수 선언.
      request.on('data', function(data){ //콜백함수. 서버에서 수신한 정보를 data 매개변수에 담음.
        body = body + data; //데이터가 전송될 때마다, 빈 변수 body에다가 전송된 데이터를 추가해줌.
      });
      request.on('end', function(){ // 데이터를 호출하다가, 데이터를 다 받은 뒤 할 실행될 함수.
        var post = qs.parse(body); //포스트에 바디에 저장된, 데이터를 querystring body부분을 통해 전달받음.
        var title = post.title;
        var description = post.description;
        fs.writeFile(`data/${title}`, description, 'utf8', function(error){
          //200 성공,  404 실패, 302 리다이렉션
          response.writeHead(302, {Location: `/?id=${title}`}); 
          response.end(); //화면출력하는부분
        })
      });
    
    //pathname이 update일 때, 즉 '수정'기능을 수행하는 조건문을 추가.
    } else if(pathname === '/update'){
      //디렉토리를 읽는 함수 filelist변수가 파일목록. 배열로 반환.
      fs.readdir('./data', function(err, filelist){
      //파일을 읽는 함수. description변수가 파일.
      fs.readFile(`data/${queryData.id}`, 'utf-8', function(err, description){
        var title = queryData.id
        var list = templateList(filelist);
        var template = templateHTML(title, list, 
        `
        <!--form 태그-->
        <form action="http://localhost:3000/update_process" method="POST">
          <input type="hidden" name="id" value="${title}">
          <p><input type="text" name="title" placeholder="수정할 제목" value=${title}></p>
          <p><textarea name="description" placeholder="수정할 본문입력">${description}</textarea></p>
          <p><input type="submit"></p>
        </form> 
        `,
        `<a href="/create">Create</a> 
        <a href="/update?id=${title}">Update</a>`
        );
        response.writeHead(200); // 페이지가 정상적으로 출력되면 200, 오류페이지면 404.
        response.end(template); //화면출력하는부분
        });
      });

    //위에서 '수정'기능을 사용해 보낸 데이터를 받는 부분. pathname 이 update_process일 때 조건문.
    } else if(pathname === '/update_process'){
      var body=''; // body에 빈 변수 선언.
      request.on('data', function(data){ //콜백함수. 서버에서 수신한 정보를 data 매개변수에 담음.
        body = body + data; //데이터가 전송될 때마다, 빈 변수 body에다가 전송된 데이터를 추가해줌.
      });
      request.on('end', function(){ // 데이터를 호출하다가, 데이터를 다 받은 뒤 할 실행될 함수.
        var post = qs.parse(body); //포스트에 바디에 저장된, 데이터를 querystring body부분을 통해 전달받음.
        var id = post.id; // 우린 id값도 받았으니, id값도 처리해주어야하므로 id 변수생성.
        var title = post.title;
        var description = post.description;
        fs.rename(`data/${id}`, `data/${title}`, function(error){ //제목을 바꾸는..
          fs.writeFile(`data/${title}`, description, 'utf8', function(error){ //본문을 바꾸는..
            //200 성공,  404 실패, 302 리다이렉션
            response.writeHead(302, {Location: `/?id=${title}`}); //수정한 페이지로 이동..
            response.end(); //화면출력하는부분
          })
        });
      });

    // '삭제'기능을 사용해 보낸 데이터를 받는 부분. pathname 이 update_delete 때 조건문.
    } else if(pathname === '/delete_process'){
      var body=''; // body에 빈 변수 선언.
      request.on('data', function(data){ //콜백함수. 서버에서 수신한 정보를 data 매개변수에 담음.
        body = body + data; //데이터가 전송될 때마다, 빈 변수 body에다가 전송된 데이터를 추가해줌.
      });
      request.on('end', function(){ // 데이터를 호출하다가, 데이터를 다 받은 뒤 할 실행될 함수.
        var post = qs.parse(body); //포스트에 바디에 저장된, 데이터를 querystring body부분을 통해 전달받음.
        var id = post.id; // 우린 id값도 받았으니, id값도 처리해주어야하므로 id 변수생성.
        fs.unlink(`data/${id}`, function(error){
          response.writeHead(302, {Location: `/`}); // 홈페이지로 이동..
          response.end(); //화면출력하는부분
        }
      )
    });

    //요청한 pathname이 루트값이 아니고, qeuryData.id가 없다면 즉, 오류페이지 실행.    
    } else {
      response.writeHead(404); // 페이지가 정상적으로 출력되면 200, 오류페이지면 404.
      response.end('NOT FOUND'); //화면출력하는부분
    }

});
app.listen(3000); // 3000번 포트를 서버로 사용하겠다. 선언.

- E N D -