공부 저장소/Node.js

[생활코딩 Node.js] 14. 데이터 받아서 파일 저장하기

tipsygypsy 2022. 8. 4. 20:33

POST 방식 데이터 받아서 파일로 저장하기

이제 데이터를 입력할 수 있게 만들었으니, 받아서 쓰는 부분도 만들어 준다.

입력form에서 제출 버튼을 눌렀을 때 이동하는 주소를 /create_process 라고 지정했으니 해당 주소에 대한 페이지를 조건문을 사용해 하나 더 만들어 준다.

else if(pathname === '/create_process'){
    response.writeHead(200);
    response.end('success');
  }

일단 잘 작동하는지 확인하기 위해 리턴 부분에 success라는 텍스트를 넣었다. 제출 버튼을 누르면 화면에 success라고 뜨는 것이 확인된다. 작동 확인 완료.

이제 실제로 입력 내용을 받아오는 기능 구현을 위해 코드를 아래와 같이 수정한다.

request.on(data) 부분은 제출된 데이터를 여러 번에 걸쳐 받아오는 부분이고, 데이터가 끝나면 request.on(end) 부분이 실행된다. 이 내용은 post 방식으로 전달되었으므로 주소입력창에 노출되지는 않지만 사실 querystring 에 담겨서 넘어오기 때문에, qs.parse 함수를 이용하여 적절하게 파싱해 준다. 잘 되었는지 확인하기 위해 파싱된 내용을 로그로 찍는 부분까지 추가.

//코드 가장 상단에 추가
var qs = require('querystring');

//중간 생략
else if(pathname === '/create_process'){
    var body = '';
    request.on('data', function(data){
      //callback 함수가 실행될 때마다 body에 data 추가
      body = body + data;
    });
    request.on('end', function(){
      //정보 수신이 끝나면 end가 호출됨
      var post = qs.parse(body);
      console.log(post);
    });
    response.writeHead(200);
    response.end('success');
  }

실행해 보니 cmd에 띄워 놓은 pm2 log에 아래와 같은 출력이 떴다.

0|main  | [Object: null prototype] {
0|main  |   title: 'java',
0|main  |   description: 'java is...            '
0|main  | }

이제 이렇게 전송받은 데이터를 이용해 새로운 파일을 만들어 목록에 추가하는 작업을 진행해 본다. 사실 data 디렉터리에 새로운 파일이 생기면 해당 페이지를 자동으로 만들어 주는 기능은 진작 적용이 되어 있는 상태이므로, 받아온 데이터의 내용으로 새로운 파일을 만들어 주는 작업만 하면 그 뒤는 저절로 될 것이다.

request.on(end) 부분에 파일을 만드는 코드를 추가해 준다.

else if(pathname === '/create_process'){
    var body = '';
    //이벤트 시작
    request.on('data', function(data){
      //callback 함수가 실행될 때마다 body에 data 추가
      body = body + data;
    });
    request.on('end', function(){
      //정보 수신이 끝나면 end가 호출됨
      var post = qs.parse(body);
      var title = post.title;
      var description = post.description;
      fs.writeFile(`data/${title}`, description, 'utf-8', function(err){
        response.writeHead(200);
        response.end('success');
      });
    });
    //이벤트 종료
  }

수정한 파일을 저장한 후 create 페이지로 들어가 다음과 같이 입력하고 제출하면

일단 성공 메시지가 출력되고,

파일 목록을 보면 새로운 파일이 추가되어 있는 것을 확인할 수 있다.

물론 홈으로 들어가면 새로운 파일명으로 리스트가 생성되어 있는 것도 확인된다.

그러면 새로운 데이터를 입력했을 때, 빈 화면이 아닌 바로 생성된 파일의 화면으로 이동해서 게시글(그렇다 이것이 바로 글을 입력할 수 있는 게시판이다)의 업로드를 확인할 수 있도록 리다이렉션을 걸어 주는 작업까지 해 본다.

마지막 response 부분을 아래와 같이 바꿔 준다. 원래 200이었는데 그건 성공이라는 뜻이고, 302는 리다이렉션 코드이다(라고 이해했다 찾아보면 좀더 자세히 알 수 있을텐데 나중에..)

response.writeHead(302, {Location : `/?id=${title}`});
response.end();

그리고 아래와 같이 글을 쓰면

이렇게 새로운 목록이 업로드됨과 동시에 해당 페이지로 자동으로 이동하여 방금 쓴 글을 확인할 수 있게 되었다.

 

전체 코드

더보기
var http = require('http');
var fs = require('fs');
var url = require('url'); //url모듈 사용
var qs = require('querystring');

function templateHTML(title, list, body){
  return `
  <!doctype html>
  <html>
  <head>
  <title>WEB1 - ${title}</title>
  <meta charset="utf-8">
  </head>
  <body>
  <h1><a href="/">WEB</a></h1>
  ${list}
   <a href="/create">create</a>
  ${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 = i + 1
  }
  list = list + '</ul>';
  return list;
}

var app = http.createServer(function(request,response){
  var url_add = request.url;
  var queryData = url.parse(url_add, true).query;
  var pathname = url.parse(url_add, true).pathname;

  if(pathname === '/'){
    if(queryData.id === undefined){
      fs.readdir('./data', function(error, filelist){
        var title = 'Welcome';
        var description = 'Hello, Node.js';
        var list = templateList(filelist);
        var template = templateHTML(title, list, `<h2>${title}</h2>${description}`);

        response.writeHead(200);
        response.end(template);
      });
    } else {
      fs.readdir('./data', function(error, filelist){
        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}`);

          response.writeHead(200);
          response.end(template);
        });
      });
    }
  } else if(pathname === '/create'){
    fs.readdir('./data', function(error, filelist){
      var title = 'Web - Create';
      var list = templateList(filelist);
      var template = templateHTML(title, list, `
        <form class="" action="http://localhost:5000/create_process" method="post">
          <p><input type="text" name="title" placeholder="제목"></p>
          <p>
            <textarea name="description" rows="8" cols="60" placeholder="내용"></textarea>
          </p>
          <p>
            <input type="submit">
          </p>
        </form>
        `);

      response.writeHead(200);
      response.end(template);
      });
  } else if(pathname === '/create_process'){
    var body = '';
    //이벤트 시작
    request.on('data', function(data){
      //callback 함수가 실행될 때마다 body에 data 추가
      body = body + data;
    });
    request.on('end', function(){
      //정보 수신이 끝나면 end가 호출됨
      var post = qs.parse(body);
      var title = post.title;
      var description = post.description;
      fs.writeFile(`data/${title}`, description, 'utf-8', function(err){
        response.writeHead(302, {Location : `/?id=${title}`});
        response.end();
      });
    });
    //이벤트 종료
  } else {
    // 존재하지 않는 pathname일 경우 에러처리
    response.writeHead(404);
    response.end('Not found');
  }

});
app.listen(5000);