본 게시글은 유튜브 생활코딩 온라인 강의를 시청한 후 학습한 정보를 기록하는 목적의 게시글입니다.

생각의 흐름에 따라 작성된 게시글입니다. 가독성이 떨어질 수 있습니다.

생활코딩 유튜브

 

생활코딩

일반인에게 프로그래밍을 알려주는 온라인/오프라인 활동 입니다.

www.youtube.com

생활코딩 사이트

 

생활코딩

hello world 생활코딩의 세계에 오신 것을 환영합니다. 생활코딩은 일반인들에게 프로그래밍을 알려주는 무료 온라인, 오프라인 수업입니다.  어떻게 공부할 것인가를 생각해보기 전에 왜 프로그래밍을 공부하는 이유에 대한 이유를 함께 생각해보면 좋을 것 같습니다. 아래 영상을 한번 보시죠. 온라인 강의 소개 입문자의 가장 큰 고충은 '무엇을 모르는지 모르는 상태'일 겁니다. 온라인에는 프로그래밍을 익히는 데 필요한 거의 모든 정보가 있지만, 이 지식들은

opentutorials.org

"프레임워크는 현실의 복잡함으로 부터 우리를 구원해 줄

우리의 구원자가 될 것입니다."

(생활코딩 : Web3 - express 수업 소개. 중)


#0.

상세보기 페이지를 Express 버전으로 변환해볼 것입니다.

이 과정에서 query string을 사용하지 않는,

pretty url(clean url, semantic url..)로 라우트 기능을 구현하는 방법을 살펴보겠습니다. 

 

#1.

지금 현재의 코드는 query string을 통해서 데이터를 전달하고 있다.

HTML 이란 id값을 통해서 data 디렉토리의 HTML 파일을 읽어오는 방식이다.

그런데 최근 웹개발 동향은 주소창에 query string이 들어있는 것을 지양한다.

미학적인 측면..? 검색엔진 최적화..? 아무튼,

이를 구현하기 위해 라우팅 가이드를 참조해보자.

 

Express routing

Routing Routing refers to how an application’s endpoints (URIs) respond to client requests. For an introduction to routing, see Basic routing. You define routing using methods of the Express app object that correspond to HTTP methods; for example, app.ge

expressjs.com

위의 게시글을 확인해보면 Route path가 "/users/:userId/books/:bookId" 일 때, 

실제 사용자가 접속하는 URL이 "http://localhost:3000/users/34/books/8989" 이면

userId가 34로, bookId가 8989로 대응됨을 확인할 수 있다.

app.get('/page', (req, res)  =>
res.send('/page')
);

app.get('/page/:pageId', (req, res)  =>
  res.send(req.params)
);

직접 확인해보자.

 

#2.

app.get('/page/:pageId', (request, response) =>
  fs.readdir('./data', function(error, filelist){
    var filteredId = path.parse(request.params.pageId).base;
    fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
      var title = request.params.pageId;
      var sanitizedTitle = sanitizeHtml(title);
      var sanitizedDescription = sanitizeHtml(description, {
        allowedTags:['h1']
      });
      var list = template.list(filelist);
      var html = template.HTML(sanitizedTitle, list,
        `<h2>${sanitizedTitle}</h2>${sanitizedDescription}`,
        ` <a href="/create">create</a>
          <a href="/update?id=${sanitizedTitle}">update</a>
          <form action="delete_process" method="post">
            <input type="hidden" name="id" value="${sanitizedTitle}">
            <input type="submit" value="delete">
          </form>`
      );
      response.send(html);
    });
  })
);
 

기존의 코드에서는 queryData.id를 사용한 반면에 우리는 이제 pageId를 사용함으로 해당 내용을 수정해주었다.

var path = require('path');
var sanitizeHtml = require('sanitize-html');

코드 상단에 필요한 모듈을 정의해주는 것도 잊지 말자.

현재 Main페이지의 "<a href="/? id=HTML"> HTML </a>"를 클릭하면,

URL이 "http://localhost:3000/? id=HTML"인 것을 확인할 수 있는데, 이 역시 /lib/template.js에서 변경해주자.

...
    while(i < filelist.length){
        list = list + `<li><a href="/page/${filelist[i]}">${filelist[i]}</a></li>`;
        i = i + 1;
    }
...

이번 시간에는 URL Path방식으로 파라미터를 전달하는 것을 처리하는 라우팅 기법에 대해서 알아보았다.


#0.

이전 시간에 배웠던 내용과 대동소이하다.

애초에 이미 node.js 과정에서 이미 다 만든 코드를 가지고 작업하기에...

비슷한 내용에 큰 시간을 들이지 않고 진도를 나가보자.

 

#1.

이전과 마찬가지로 express의 방식으로 페이지 생성 기능을 전환하자.

app.get('/create', (request, response) =>
  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">
        </p>
      </form>
    `, '');
  response.send(html);
  })
)

 

#2.

create를 살펴보면 form에서 post방식으로 "/create_process"를 호출하는 것을 확인할 수 있다.

이 역시 express 방식으로 구현하자.

app.post('/create_process', (request, response) =>{
  var body = '';
  request.on('data', function(data){
    body = body + data;
  });
  request.on('end', function(){
    var post = qs.parse(body);
    var title = post.title;
    var description = post.description;
    fs.writeFile(`data/${title}`, description, 'utf8', function(err){
      response.redirect( `/page/${title}` );
    })
  })
})

 생활코딩 강의에서는 따로 설명되어 있지 않지만 redirect 부분도 express의 문법에 맞게 변경해주었다.

원래는 아래의 코드와 같다.

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

제대로 동작하는지 확인을 위해서 querystring 모듈 역시 상단에서 호출해주자.

var qs = require('querystring');

#1.

다음으로 페이지 수정 기능을 구현해보자.

먼저 pageId를 생성해주는 부분에서 clean URL을 위해 update부분을 수정해주자.

app.get('/page/:pageId', (request, response) =>
    ...
          <a href="/update/${sanitizedTitle}">update</a>
    ...
)

 

#2.

이후 update 부분 코드를 express 방식으로 바꾸어주자.

pageId를 만들었을 때를 기억하며 "request.params.pageId"를 사용하는 것을 유의하자.

app.get('/update/:pageId', (request, response) => {
  fs.readdir('./data', function(error, filelist){
  var filteredId = path.parse(request.params.pageId).base;
  fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
    var title = request.params.pageId;
    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">
        </p>
      </form>
      `,
      `<a href="/create">create</a> <a href="/update?id=${title}">update</a>`
    );
    response.send(html);
  });
  });
});

 

#3.

create와 마찬가지로 post방식으로 update_process를 호출하고 있는 것을 확인할 수 있다.

마찬가지로 구현해주자. 

app.post('/update_process', (request, response) =>{
  var body = '';
      request.on('data', function(data){
          body = 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, 'utf8', function(err){
        response.redirect(`/page/${title}`);
      })
    });
  });
})

"create_process"와 마찬가지로 redirect부분을 수정해주었다.

그런데 인터넷을 돌아다보니면 아래와 같은 코드를 만날 수 있는데...

response.redirect(302, `...`);

302는 HTML status code에서 "발견되었다"의 의미를 가진다.

따로 지정해주지 않으면(현재 나의 코드처럼) 기본값으로 302를 가지게 된다. (아래 사진 참조)

HTML status code에 대한 자세한 설명은 이 게시글을 참조하자.

 

HTTP/1.1: Status Code Definitions

part of Hypertext Transfer Protocol -- HTTP/1.1 RFC 2616 Fielding, et al. 10 Status Code Definitions Each Status-Code is described below, including a description of which method(s) it can follow and any metainformation required in the response. 10.1 Inform

www.w3.org


#1.

드디어 CRUD의 마지막 D, 삭제 기능이다.

특별히 달라지는 점은 없으니 마찬가지로 구현하자.

pageId를 생성해주는 부분에서 delete는 post방식으로 구현하고 있음을 알 수 있다.

app.post('/delete_process', (request, response) => {
  var body = '';
  request.on('data', function(data){
      body = 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}`, function(error){
        response.redirect(`/`);
      })
  });
})

마찬가지로 URL 체계도 통일하여 수정해주자.

app.get('/page/:pageId', (request, response) =>
    ...
          <form action="/delete_process" method="post">
            <input type="hidden" name="id" value="${sanitizedTitle}">
            <input type="submit" value="delete">
          </form>
    ...
)

강의에서 언급을 안하시길래 생략하시는 줄 알았는데 지금 강의에서 redirect의 코드를 정정해주신다.

만들면서 이미 다 바꾸었기에 아래의 게시글을 통해 한번 더 개념만 다시 정리하고 넘어가자.

 

Express 4.x - API 참조

Express 4.x API express() Creates an Express application. The express() function is a top-level function exported by the express module. var express = require('express') var app = express() Methods express.json([options]) This middleware is available in Ex

expressjs.com

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기