웹서버와 클라이언트(웹브라우저) 사이에서 데이터가 오고가는 과정을 보면
Http request 와 Http response라는 개념을 사용합니다.
Http request
는 어떤 작업을 요청할 때, 웹브라우저가 서버에 보낸 정보들을 의미하며
Http response
는 어떤 요청에 대한 응답으로서, 서버가 웹브라우저에 전송할 정보들을 의미합니다.
Node.js에서 http를 호출할 수 있는 방법 중 두 가지를 소개하겠습니다.
먼저, 내장되어 있는 http 모듈을 사용하거나 Request 모듈을 설치하여 사용할 수 있습니다.
내장 http 모듈로 호출하기
다음의 코드는
- http모듈을 이용하여 서버를 구동
- (프로젝트 폴더 하위의)data폴더 내 파일 목록을 가져와 출력
- 각 파일명 클릭 시 파일 본문이 html태그로 출력
- create문구 클릭 시 폼 태그 출력
- 폼 입력 후 submit하면 create_process라는 새로운 경로로 리다이렉트
와 같이 다섯가지 기능을 담고 있습니다.
//파일명: main.js
var http = require('http');
var fs = require('fs'); //파일 가져오기 위한 변수
var url = require('url');
var qs = require('querystring'); //node가 가지고 있는 모듈
//웹페이지에서 공통된 템플릿(html 태그들)을 반환하는 함수
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>
`;
}
//파일 목록을 html 리스트 형식으로 반환하는 함수
function templateList(filelist) {
var list = '<ul>';
var i = 0;
//파일 목록 개수만큼 항목(li태그)가 추가됨
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 = request.url;
var queryData = url.parse(_url, true).query;
var pathname = url.parse(_url, true).pathname;
//url 'localhost:3000/'에 대한 웹페이지 로딩
if (pathname === '/') {
//전송받은 쿼리데이터가 없는 경우
if (queryData.id === undefined) {
fs.readdir('./data', function (error, filelist) {
var title = '안녕하세오';
var description = 'Hello, Node.js( ღ’ᴗ’ღ )';
var list = templateList(filelist); //파일 목록 리스트 태그
var template = templateHTML(title, list, `<h2>${title}</h2>${description}`);
response.writeHead(200);
response.end(template); //송수신이 끝난 후 서버가 웹브라우저에 전송할 코드. 즉 html태그들이 그려지겠죠?
});
} 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}`);
response.writeHead(200);
response.end(template);
});
});
}
}
//url 'localhost:3000/create' 에 대한 웹페이지 로딩
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="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>
`);
response.writeHead(200); //서버가 웹브라우저에게 데이터를 잘 받았음을 의미하는 숫자코드(200)
response.end(template);
});
}
//폼 제출(POST방식) 후 페이지
else if (pathname === '/create_process') {
var body = '';
request.on('data', function (data) {
body = body + data;
});
request.on('end', function () {
var post = qs.parse(body); //querystring 모듈이 가지는 parse함수는 body를 입력값으로 받아 '객체화' 시킨다.
/*
여기서 post 값은 post = { title: ' ... ', description: ' ... ' } 와 같은 객체 형태이다.
객체에서 속성값에 접근하기 위해서는 . 으로 접근한다는 점을 기억하자.
*/
var title = post.title;
var description = post.description
});
response.writeHead(200);
response.end('SUCCESS');
} else {
response.writeHead(404);
response.end('Not found');
}
});
app.listen(3000);
파일의 내용이 변경된 경우 서버를 껐다가 다시 구동시켜야 변경사항이 반영됩니다! 주의주의
웹브라우저가 post방식으로 데이터를 전송할 때 데이터가 무수히 많을 경우 프로그램이 꺼지는 등의 오류를 대비하여 서버쪽에서 적당량의 데이터를 수신할 때마다 콜백함수를 호출하도록 약속한다. 그렇게 수신되다가 더이상 수신할 데이터가 없을 경우에 ‘end’라는 이벤트에 대한 콜백함수가 호출되도록 하는 것이다. 즉, 이때가 바로 데이터 송수신이 끝난 시점이다.
request.on()
에 쓰인 data
와 end
는 이벤트 이름이다.
Request 모듈로 호출하기
이 모듈은 Http는 물론 Https 호출 또한 지원하며 다음의 npm 명령을 통해 설치할 수 있어요.
npm install request
(다음에 추가링,,)
- 참고 자료
https://opentutorials.org/course/3332/21136 : 코드 참고
https://www.npmjs.com/package/request : request 모듈 설명 docs