codingeverybody / codingyahac

https://coding.yah.ac
292 stars 50 forks source link

생활코딩 web2 node.js 36강 강의 재질문 #825

Open leewonje418 opened 5 years ago

leewonje418 commented 5 years ago

해결하고자 하는 문제

update버튼을 누르고 재목을 수정하면 재목이 수정되어야되는대 재목수정이 안되고 새로운 재목이 하나 더 생깁니다. (css링크를 클릭하고 update버튼을 누른 후 재목을 css3로 수정하면 css라는 제목이 css3로 바뀌는게 아니라 css, css3라는 재목을 가진 개시물이 하나 더 생깁니다.)

코드 혹은 오류

   여기에 코드를 적어주세요. 
var http = require('http');
var fs = require('fs');
var url = require('url');
var qs = require('querystring');

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</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;
    var queryData = url.parse(_url, true).query;
    var pathname = url.parse(_url, true).pathname;
    console.log("pathname ", 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}`,
              `<a href="/create">create</a>`
            );
            response.writeHead(200);
            response.end(template);
          })
      } else {
        fs.readdir('./data', function(error, filelist){
          fs.readFile(`data/${queryData.id}`, `utf8`, 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>`
            );
            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 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">
          </p>
        </form>
      `, '');
      response.writeHead(200);
      response.end(template);
    });
  } else if(pathname === '/create_process'){
    var body ='';
    request.on('data', function(data){
      body += data;
    });
    request.on('end', function(){
      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 if(pathname === '/update'){
    fs.readdir('./data', function(error, filelist){
      fs.readFile(`data/${queryData.id}`, `utf8`, function(err, description){
        var title = queryData.id;
        var list =  templateList(filelist);
        var template = templateHTML(title, list,
          `
          <form action="/update_process" method = "post">
            <input type="hidden" name="title" placeholder="title" 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);
    });
  });
} else if(pathname === '/update_process'){
  var body ='';
  request.on('data', function(data){
    body += data;
  });
  request.on('end', function(){
    var post = qs.parse(body);
    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, 'utf-8', function(err){
        response.writeHead(302, {Location: `/?id=${title}`});
        response.end();
      })
    });
  });
} else {
    response.writeHead(404);
    response.end('Not found');
  }
});
app.listen(3000);

환경

사용중인 운영체제, 언어, 라이브러리의 버전을 적어주세요. atom, node.js

시도해본 방법

Haytsir commented 5 years ago
} 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 =  templateList(filelist);
        var template = templateHTML(title, list,
          `
          <form action="/update_process" method = "post">
            <input type="hidden" name="id" placeholder="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);
    });
  });
}

위 처럼 수정되어야 합니다.

문제 원인은,

<form action="/update_process" method = "post">
    <input type="hidden" name="title" placeholder="title" 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>

name="title" 속성을 가진 input태그가 두 개 존재해서, 서버에 전송된 title 정보가 두 개였습니다. 결국 [ 브라우저 ] ====> { [title 값1, title 값2], description 값 } ====> [ 서버 ] 처럼 보내졌고,

서버 내부에서 수행하는 코드는

fs.rename(`data/${id}`, `data/${title}`, function(error){
    fs.writeFile(`data/${title}`, description, 'utf-8', function(err){
        response.writeHead(302, {Location: `/?id=${title}`});
        response.end();
    })
});

인데,

실제로 실행된 내용은 id가 undefined 였으므로

  1. data/undefined 파일을 data/title 값1,title 값2로 이름을 바꾼 후, (파일을 찾을 수 없었으므로 아무 작업도 하지 않습니다.)
  2. data/title 값1,title 값2 파일에 description 값 내용을 씁니다. (원래는 존재하는 파일과 같은 이름으로 파일을 생성하여, 덮어쓰는 용도로 사용했지만, 해당 파일이 존재하지 않아 새로 만들어진 상황입니다.)