Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

9시 24분

글 수정, 글 삭제, 객체 문법, 템플릿 정리정돈, 모듈, 입력정보에 대한 보안, 출력정보에 대한 보안 본문

카테고리 없음

글 수정, 글 삭제, 객체 문법, 템플릿 정리정돈, 모듈, 입력정보에 대한 보안, 출력정보에 대한 보안

leeeee.yeon 2021. 5. 24. 01:40
글 수정 - 수정 링크 생성

 

templateHTML 함수를 아래와 같이 수정해주자

function templateHTML(title, list, body, control){
    return `
    <!doctype html>
    <html>
    <head>
      <title>WEB - ${title}</title>
      <meta charset="utf-8">
    </head>
    <body>
      <h1><a href="/">WEB</a></h1>
      ${list}
      ${control}
      ${body}
    </body>
    </html>
    `;
}
  • control 변수 추가

 

그리고 각 섹션(홈, 페이지, create 창)마다 상황에 맞게 update 버튼이 뜨도록( 안 뜨도록 ) 해주자.

홈 - 안 뜸

페이지 - 뜸

create 창 - 안 뜸 ( create 버튼도 )

 

그리고, 각 페이지 창에서 아래 코드처럼 update 뒤에 query string을 추가하여 어떤 글을 수정할 것인지 명시해주자.

// 홈
var template = templateHTML(title, list,`<h2>${title}</h2>${description}`,
	`<a href="/create">create</a>`);
    
// 페이지
var template = templateHTML(title, list,`<h2>${title}</h2>${description}`,
	`<a href="/create">create</a> <a href="/update?id=${title}">update</a>`);
    
// create 창
var template = templateHTML(title, list,`
<form action="http://localhost:3000/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">
	</p>
</form>
`, ``);

 

글 수정 - 수정할 정보 전송

 

else if(pathname==='/create_process') 아래에 아래 코드를 추가해주자.

else if(pathname === '/update'){
      fs.readdir('./data',function(error, fileList){
        var list = templateList(fileList);
        fs.readFile(`data/${queryData.id}`, 'utf8', function(err, description){
          var title=queryData.id;
          var template = templateHTML(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">
            </p>
          </form>
          `,
          `<a href="/create">create</a> <a href="/update?id=${title}">update</a>`);
        response.writeHead(200);
        response.end(template);
        });
      });
    }
  • fs.readdir() 함수로 내용을 읽어옴
  • input 태그에선 value 속성, textarea 태그에선 본문에 literal을 사용해주어서 원래 글의 제목과 본문을 기본 값으로 받아온다.
  • 제목 수정 시, data 디렉토리의 파일명과 수정한 제목이 일치하지 않을수도 있다! 그러므로 원래 제목과 수정된 제목을 데이터로 전송받을 때 둘 다 전송받기 위해 hidden 태그를 사용한다.

 

글 수정 페이지
개발자 도구 - 네트워크에서 전송된 데이터를 확인

 

글 수정 - 파일명 변경, 내용 저장

이전에 글 생성에서 했던 것을 참고하여 아래와 같이 if문을 추가해주자.

else if(pathname === '/update_process'){
      var body = '';
      request.on('data', function(data){
        // 데이터가 많을 경우 조각조각의 데이터를 인자로 콜백 함수를 호출 > 수신한 정보를 줌
          body += data;
      });
      request.on('end', function(){ // 더 이상 들어올 정보가 없으면 콜백 함수를 호출
        var post = qs.parse(body); // post 안에 POST 데이터가 들어있을 것
        var id = post.id;
        var title = post.title;
        var description = post.description;
        fs.rename(`data/${id}`, `data/${title}`, function(error){
          fs.writeFile(`data/${title}`, description, 'utf8', function(err){ // 에러가 있을 때 에러를 처리하는 방법
            response.writeHead(302, {Location: `/?id=${title}`}); // 302 - 리다이렉션
            response.end('sucess'); 
          });
        });
      });
  • fs.rename() 함수를 이용하여 글 수정 시 제목이 바뀌도록 해줬다.
  • 콜백 함수에는 fs.writeFile() 함수를 이용하여 내용도 바뀔 수 있도록 해줬다.
  • 앗, 그리고 앞에서 설명 안했는데 코드의 간결성을 위해 앞에 localhost:3000 부분도 생략해주었당

짜잔 잘 바뀐당
내용도 잘 바뀌는거 check
웹 페이지에서도 check

 

글 삭제 - 삭제버튼 구현

delete 버튼을 구현하고, delete 했을 때 data 디렉토리에서 제목이 같은 파일을 삭제할 수 있도록 하자.

 

delete 버튼은 링크, GET 방식으로 만들면 안돼 > form 태그로 만들어줄거야

 

각 페이지를 나타내는 else 문을 아래와 같이 수정해주자.

 

      else{ // 페이지
        fs.readdir('./data',function(error, fileList){
          var list = templateList(fileList);
          fs.readFile(`data/${queryData.id}`, 'utf8', function(err, description){
            var title=queryData.id;
            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="확인문구 js">
            <input type="hidden" name="id" value="${title}">
            <input type="submit" value="delete">
            </form>
            `);
          response.writeHead(200);
          response.end(template);
          });
        });
      }
  • template 수정 > form 태그 추가, hidden 타입과 submit 타입 input 태그 각각 하나씩 생성

 

글 삭제 - 삭제 기능 완성
else if(pathname === '/delete_process'){
      var body = '';
      request.on('data', function(data){
        // 데이터가 많을 경우 조각조각의 데이터를 인자로 콜백 함수를 호출 > 수신한 정보를 줌
          body += data;
      });
      request.on('end', function(){ // 더 이상 들어올 정보가 없으면 콜백 함수를 호출
        var post = qs.parse(body); // post 안에 POST 데이터가 들어있을 것
        var id = post.id;
        fs.unlink(`data/${id}`, function(error){
          response.writeHead(302, {Location: `/`}); // 302 - 리다이렉션
          response.end(); 
        })
      });
    }
  • fs.unlink() 함수를 이용하여 data 디렉토리에서 파일을 삭제하고 메인 화면으로 돌아올 수 있도록 하자.
  • delete 버튼을 눌렀는데 계속 메인으로 가기만 하고 글 삭제 기능이 안되는거임 ㅠㅠ 알고보니까 위에서 delete 버튼 만들 때 =를 안 입력해줘서 value 속성이 제대로 작동 안하는거였음

 

객체 문법
// syntax/object.js

var roles = {
    'backend' : 'BB',
    'frontend' : 'FF',
    'manager' : 'MM'
}

console.log(roles.backend);

for(var name in roles){
    console.log('object -> ', name, ', value -> ', roles[name]);
}

 

객체 - 값으로서 함수
var f = function(){
    console.log(1+1);
    console.log(2+2);
}

var a = [f];
a[0]();

console.log(f);
f();

var o = {
    func: f
}
o.func();

셋 다 같은 역할

 

템플릿 기능 정리정돈

 

위에서 배운 객체 개념을 활용하여 비슷한 개념인 templateList, templateHTML 함수를 객체로 만들고, 그에 맞게 아래 코드들도 template.list & template.HTML 로 수정해주었다.

var template = {
  HTML : function(title, list, body, control){
    return `
    <!doctype html>
    <html>
    <head>
      <title>WEB - ${title}</title>
      <meta charset="utf-8">
    </head>
    <body>
      <h1><a href="/">WEB</a></h1>
      ${list}
      ${control}
      ${body}
    </body>
    </html>
    `;
  }

 

모듈

: 파일을 쪼개서 관리

 

// muse.js

var M = {
    v : 'v',
    f : function(){
        console.log(this.v);
    }
}

M.f(); // 이거랑

var part = require('./mpart.js');
part.f(); // 이거 같은 기능 수행

// mpart.js

var M = {
    v : 'v',
    f : function(){
        console.log(this.v);
    }
}

module.exports = M; // 모듈이 담긴 mpart.js 중 M이 가리키는 객체를 모듈 밖에서 사용할 수 있도록 한다.

 

우리의 애플리케이션에 활용해보자.

 

template 객체를 모듈화하자.

// template.js

var template = {
    HTML : function(title, list, body, control){
      return `
      <!doctype html>
      <html>
      <head>
        <title>WEB - ${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;
    }
  }

module.exports = template;

 

그 다음 main.js에 있던 저 부분을 지우고 아래 코드를 추가하자.

var template = require('./lib/template.js');

 

입력정보에 대한 보안

...은 pass