상세 컨텐츠

본문 제목

Node.js / 라우터 분기 처리 / 쿠키 수집

프레임워크+라이브러리/Express

by moonionn 2020. 7. 20. 16:29

본문

Cookie가 뭐지?

Node.js를 이용하여 사용자의 데이터를 받고, 처리하는 작업을 해봅시다.

이를 위해 인터넷 쿠키를 어떻게 쓸 수 있는지도 연습해보겠습니다.

 

일단 사용자가 서버에 정보를 전달할 수 있도록 <form> 태그를 담은 html 파일을 만들어줍니다.

server_content.html이라는 이름으로 파일을 생성했습니다.

 

HTML 생성

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>practice</title>
</head>
<body>
  <h1>왕초보자의 웹서버 생성 연습</h1>
  <h2>
    웹서버와 이용자간에 데이터를 어떻게 교환하는지 node js를 이용해 알아봅시다. <br /> 
    우선 아래에 본인의 이름과 생년월일을 적어주세요.
  <h2>
  <form action="/user">
    <b>이름</b>
    <input type="text" name="name" placeholder="이름을 입력해주세요" />

    <b>생년월일</b>
    <input type="date" name="birth_date" />

    <button>확인</button>
  </form>
</body>
</html>

<form action="/user"> 는 데이터가 submit되는 순간 (여기서는 button을 누르는 순간)

action 이 가리키는 /user 주소로 사용자를 보내줍니다.

이제 이 html 파일을 읽어줄 js 파일을 작성해봅시다.

 

createServer

const http = require('http');
const fs = require('fs');

const server = http.createServer((req, res) => {
  fs.readFile('./server_content.html', (err, data) => {
    res.end(data);
  });
});
server.listen(8000);

정상적으로 작동하는 모습

 

Cookie 설정

이제 쿠키를 어떻게 사용하는지 알아봅시다.

쿠키를 설정할 때에는 Set-Cookie를 이용하며, 'Set-Cookie': 'key = value' 로 값을 전달합니다.

const http = require('http');
const fs = require('fs');

const server = http.createServer((req, res) => {
  fs.readFile('./server_content.html', (err, data) => {
    res.writeHead(200, {'Set-Cookie': 'user-info = testing'});
    res.end(data);
  });
});
server.listen(8000);

콘솔창을 키고 네트워크란에 들어가서 확인해보면,

res.writeHead()로 인해 Headers 부분에 Cookie의 내용이 변경된 것을 확인할 수 있습니다.

 

 

또한 Application란에 들어가서 Storage 목록 중 Cookies 를 보면,

우리가 설정한 key값과 value값이 잘 들어가 있는 걸 확인할 수 있습니다.

 

라우터 분기 처리

이름과 생년월일을 대충 써줍니다.

 

이름과 생년월일을 적었으니, 확인 버튼을 누르면 웹서버는 사용자를 /user 주소로 이동시킬 것입니다.

그렇기 때문에 해당 주소를 찾아갔을 때, 어떠한 이벤트가 발생할 것인지도 정해야 합니다.

const http = require('http');
const fs = require('fs');

const server = http.createServer((req, res) => {

  const {pathname} = url.parse(req.url);
  
  if (pathname === '/user') {
    res.end('URL changed! Check it out!');
  } else {
    fs.readFile('./server_content.html', (err, data) => {
      res.writeHead(200, {'Set-Cookie': 'user-info = testing'});
      res.end(data);
    });
  };
});
server.listen(8000);

해당 /user은 pathname의 값이기 때문에 if문을 활용해보겠습니다.

해당 주소로 이동하면 'URL changed! Check it out!'이라는 문구가 나오게 설정했습니다.

 

여기서 pathname이란?

아래는 '/user'로 이동했을 시 url.parse(req.url)의 내용인데, 다음과 같이 객체가 호출됩니다.

console.log(url.parse(req.url));


result:
Url {
   protocol: null,
   slashes: null,
   auth: null,
   host: null,
   port: null,
   hostname: null,
   hash: null,
   search: '?name=%EB%B6%88%ED%83%80%EB%8A%94+%ED%82%A4%EB%B3%B4%EB%93%9C&birth_date=2020-04-01',
   query: 'nname=%EB%B6%88%ED%83%80%EB%8A%94+%ED%82%A4%EB%B3%B4%EB%93%9C&birth_date=2020-04-01',
   pathname: '/user',
   path: '/user?name=%EB%B6%88%ED%83%80%EB%8A%94+%ED%82%A4%EB%B3%B4%EB%93%9C&birth_date=2020-04-01',
   href: '/user?name=%EB%B6%88%ED%83%80%EB%8A%94+%ED%82%A4%EB%B3%B4%EB%93%9C&birth_date=2020-04-01' 
}

//따라서 아래 두 코드는 같은 코드이다.
const {pathname} = url.parse(req.url);
const pathname = url.parse(req.url).pathname;

객체의 key 중 pathname이라는 게 있는데, 그 값이 '/user'인 것을 확인할 수 있습니다.

따라서 해당 value를 불러오기 위해서는 url.parse(req.url).pathname을 이용해야 합니다.

 

혹은

if (pathname === '/user') 대신

if (req.url.startsWith('/user')) 를 사용해도 무방합니다.

코드가 정상적으로 작동하는 걸 확인할 수 있습니다.

주소 이동이 성공했으니, 이제 사용자의 정보를 받아오는 작업을 해보겠습니다.

 

전송받은 정보 이용하기

우선 사용자의 이름과 생년월일 정보를 따로 불러냅니다.

이를 위해서는 아까 pathname을 이용하기 위해 썼던 url.parse(req.url) 을 다시 한 번 사용해야 합니다.

console.log(url.parse(req.url));


result:
Url {
   protocol: null,
   slashes: null,
   auth: null,
   host: null,
   port: null,
   hostname: null,
   hash: null,
   search: '?name=%EB%B6%88%ED%83%80%EB%8A%94+%ED%82%A4%EB%B3%B4%EB%93%9C&birth_date=2020-04-01',
   query: 'nname=%EB%B6%88%ED%83%80%EB%8A%94+%ED%82%A4%EB%B3%B4%EB%93%9C&birth_date=2020-04-01',
   pathname: '/user',
   path: '/user?name=%EB%B6%88%ED%83%80%EB%8A%94+%ED%82%A4%EB%B3%B4%EB%93%9C&birth_date=2020-04-01',
   href: '/user?name=%EB%B6%88%ED%83%80%EB%8A%94+%ED%82%A4%EB%B3%B4%EB%93%9C&birth_date=2020-04-01' 
}

여기서 이름과 생년월일의 값을 도출하려면 query라는 key가 필요합니다.

따라서 const {query} = url.parse(req.url) 로 query의 값을 할당하고,

해당 쿼리를 qs.parse를 이용해 한 번 더 나누어줍니다.

qs.parse(query)에 담겨 있는 내용은 아래와 같습니다.

console.log(qs.parse(query));

//result:

[Object: null prototype] { name: '불타는 키보드', birth_date: '2020-04-01' }

qs.parse()는 쿼리스트링의 key와 value값을 담고 있는 Object를 호출합니다.

따라서 qs.parse(query).name는 사용자의 이름을, qs.parse(query).birth_date는 사용자의 생년월일을 나타냅니다.

이제 이것을 활용하여 웹페이지에 본인의 이름과 생년월일을 표기할 수 있습니다.

 

const http = require('http');
const fs = require('fs');
const url = require('url');
const qs = require('querystring');

const server = http.createServer((req, res) => {

  const {pathname} = url.parse(req.url);
  const {query} = url.parse(req.url);
  const {name} = qs.parse(query);
  const birthDate = qs.parse(query).birth_date;
  
  /*
  html에서 생년월일에 해당하는 form name을 birthDate라고 해놨었더라면
  const {birthDate} = qs.parse(query); 로 처리하면 됐었다.
  */

  if (pathname === '/user'){
    res.end(`OK! We've received your profile.
    \nYour name : ${name}, 
    \nYour birthdate : ${birthDate}`);
  } else {
    fs.readFile('./server_content.html', (err, data) => {
      res.writeHead(200, {'Set-Cookie': 'user-info = testing'});
      res.end(data);
    });
  };
});
server.listen(8000);

인코딩 문제 때문에 외계어로 나오지만, 어쨌거나 제대로 작동하고 있는 모습입니다.

 

 

쿠키에 정보 저장하기

이제 Set-Cookie를 활용하여 사용자의 이름을 쿠키에 담아보겠습니다.

const http = require('http');
const fs = require('fs');
const url = require('url');
const qs = require('querystring');

const server = http.createServer((req, res) => {
  const {pathname} = url.parse(req.url);
  const {query} = url.parse(req.url);
  const {name} = qs.parse(query);
  const birthDate = qs.parse(query).birth_date;

  if (pathname === '/user'){
    res.writeHead(200, {
      'Set-Cookie' : `name = ${encodeURIComponent(name)}`
    });
    res.end(`OK! We've received your profile.
    \nYour name : ${name}, 
    \nYour birthdate : ${birthDate}`);
  }
  else {
    fs.readFile('./server_content.html', (err, data) => {
      res.writeHead(200, {'Set-Cookie': 'user-info = testing'});
      res.end(data);
    });
  };
});
server.listen(8000);

 

 

(+추가) 사이트에서 한글이 안깨지게 표현하려면?

res.writeHead(200, {'Content-Type':'text/plain; charset=utf-8'}) 를 추가하면 됩니다.

const http = require('http');
const fs = require('fs');
const url = require('url');
const qs = require('querystring');

const server = http.createServer((req, res) => {
  const {pathname} = url.parse(req.url);
  const {query} = url.parse(req.url);
  const {name} = qs.parse(query);
  const birthDate = qs.parse(query).birth_date;

  if (pathname === '/user'){
    res.writeHead(200, {
      'Set-Cookie' : `name = ${encodeURIComponent(name)}`, 
      'Content-Type':'text/plain; charset=utf-8'
    });
    res.end(`OK! We've received your profile.
    \nYour name : ${name}, 
    \nYour birthdate : ${birthDate}`);
  }
  else {
    fs.readFile('./server_content.html', (err, data) => {
      res.writeHead(200, {'Set-Cookie': 'user-info = testing'});
      res.end(data);
    });
  };
});
server.listen(8000);

관련글 더보기

댓글 영역