node.js를 처음 접하는 개발자를 위한 스터디 자료입니다.
실습 위주로, 간단한 웹 페이지를 만들어 보는 것을 목표로 하며,
express를 활용하기에 앞서, node.js 기본 API만으로 GET/POST 처리 방식을 알아봅니다.
내용의 깊이가 있지는 않으며, 단지 node.js의 입문을 위한 가벼운 수준으로 내용이 구성되었습니다.
3. 크롬 V8 자바스크립트 엔진 기반의 자바스크립트 런타임
(이벤트 기반, 논 블로킹 I/O 모델)
Chrome V8 JavaScript 엔진
구글의 오픈 소스 자바스크립트 엔진으로, C++로 작성되어 있고, 구글 크롬 브라우저에서사용 중
ECMA-262 5번째 개정판에 따른, ECMAScript를 지원
여러 운영체제(Windows, Mac, Linux 등) 및 여러 하드웨어 플랫폼(IA-32, x64, ARM 등)에서 실행 할 수 있음
Source : https://nodejs.org/en/ , https://code.google.com/p/v8/
8. (1) 웹 페이지 요청
(2) 자료를 찾아서 응답
클라이언트(client) 서버(server)
일반적으로 웹 서버는
80번 포트를 사용
9. 포트 번호는 0부터 216인 65535까지 사용 가능
Source : https://ko.wikipedia.org/wiki/TCP/UDP의_포트_목록
well-known port registered port dynamic port
0번 ~ 1023번 1024번 ~ 49151번 49152번 ~ 65535번
21 : FTP
22 : SSH(Secure Shell)
23 : 텔넷
25 : SMTP(Simple Mail Transfer Protocol)
53 : DNS
80 : HTTP
119 : NNTP (Network News Transfer Protocol) 뉴스 그룹
194 : IRC (Internet Relay Chat)
443 : TLS/SSL 방식의 HTTP
11. 네트워크를 사용하기 때문에, 윈도우 방화벽 설정 창이 최초에 한번 뜹니다. “액세스 허용"해 줍시다.
* 이 창이 유지되고 있는 동안, webserver.js 라는 파일이 실행되어, 웹서버가 작동하게 됩니다.
12. 웹 브라우저를 띄우고, “http://127.0.0.1”로 접속
Source : https://ko.wikipedia.org/wiki/루프백
루프백(loop-back) 주소로, 자기 자신으로 접속하는 주소
13. var http = require('http');
var server = http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type' : 'text/html;charset=utf-8' });
res.end('안녕, 세계');
});
server.listen(80);
① http 모듈 획득
② 서버 생성
③ 80번 포트로 수신 대기
14. var http = require('http');
var server = http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type' : 'text/html;charset=utf-8' });
res.end('안녕, 세계');
});
server.listen(80);
① 헤더 쓰기
② 응답하고,
연결 끊기
15. http 모듈를 획득한다.
서버를 만들고,
요청을 처리할 핸들러를 지정한다.
서버가 사용할 포트를 정한다.
누군가, 80번 포트로 접속했다
HTML 문서이고, utf-8 문서라고 알려준다.
(MIME 타입 지정하기)
“안녕, 세계”라고 응답하고 접속을 끊는다.
이러한 과정을 통해, 방금 확인한 결과가 나온 것인데,
따라서, http://127.0.0.1/ 뒤에 어떠한 문자를 붙이더라도 항상 “안녕, 세계”가 화면에 출력될 것입니다.
16. Source : https://ko.wikipedia.org/wiki/MIME , http://www.sitepoint.com/web-foundations/mime-types-complete-list/
전자 우편을 위한 인터넷 표준 포맷이지만,
HTTP와 같은 통신 프로토콜에서 파일의 형태를 구분하기 위해 사용되고 있음.
Multipurpose Internet Mail Extensions
HTML 문서(.htm, .html ) : text/html
텍스트 문서(.txt ) : text/plain
자바스크립트 파일(.js) : text/javascript , application/javascript , application/x-javascript
CSS 파일(.css) : text/css
이미지 파일(.png) : image/png , image/gif , image/jpeg , image/bmp
ZIP 압축 파일(.zip) : application/zip , application/x-zip-compressed
형식이 지정되지 않은 경우 : application/octet-stream
26. var http = require('http');
var url = require('url');
var fs = require('fs');
var server = http.createServer(function (req, res) {
// 생략
});
server.listen(80);
① http 모듈 획득
② url 모듈 획득
③ fs(file system) 모듈 획득
④ 서버 만들기
⑤ 80번 포트로 수신 대기
27. var oUrl = url.parse(req.url);
if (oUrl.pathname == "/")
{
fs.readFile("index.html", function(error, data) {
res.writeHead(200, { 'Content-Type' : 'text/html;charset=utf-8' });
res.end(data);
});
}
① url 모듈을 통해, 파싱된 결과 획득
② URL에서 pathname 이 “/” 인 경우,
③ index.html 파일을 읽는다
④ 읽혀진 파일 내용으로 응답
그런데… 만약… index.html 파일이 없는 경우에는 어떻게 될까요?
28. else if (oUrl.pathname == "/place")
{
fs.readFile("place.html", function(error, data) {
res.writeHead(200, { 'Content-Type' : 'text/html;charset=utf-8' });
res.end(data);
});
}
① URL에서 pathname 이 “/place” 인 경우,
② place.html 파일을 읽는다
③ 읽혀진 파일 내용으로 응답
34. var http = require('http');
var url = require('url');
var fs = require('fs');
var querystring = require('querystring');
var server = http.createServer(function (req, res) {
// 생략
});
server.listen(80);
① http 모듈 획득
② url 모듈 획득
③ fs(file system) 모듈 획득
⑤ 서버 만들기
⑥ 80번 포트로 수신 대기
④ querystring 모듈 획득
35. var oUrl = url.parse(req.url);
if (oUrl.pathname == "/form")
{
fs.readFile(“form.html", function(error, data) {
res.writeHead(200, { 'Content-Type' : 'text/html;charset=utf-8' });
res.end(data);
});
}
① url 모듈을 통해, 파싱된 결과 획득
② URL에서 pathname 이 “/form” 인 경우,
③ form.html 파일을 읽는다
④ 읽혀진 파일 내용으로 응답
36. else if (oUrl.pathname == “/formSubmit”)
{
var arrBuffer = [];
req.on('data', function (postRawData) {
arrBuffer.push( postRawData.toString() );
});
① URL에서 pathname 이 “/formSubmit” 인 경우,
② 브라우저가 보내오는 POST 데이터를 수집해 둘 배열
③ 데이터가 올 때 마다, arrBuffer 배열에 푸시 해 모아둡니다.
37. req.on('end', function () {
var oParam = querystring.parse( arrBuffer.join("") );
fs.readFile("formSubmit.html", function(error, data) {
data = data.toString();
data = data.replace(/@name@/g, oParam.name);
data = data.replace(/@email@/g, oParam.email);
data = data.replace(/@comment@/g, oParam.comment.replace(/r*n/g, "<br />") );
res.writeHead(200, { 'Content-Type' : 'text/html;charset=utf-8' });
res.end(data);
});
});
① 웹 브라우저의 요청이 끝났을 때,
② 모아 두었던 배열을 합쳐서,
쿼리스트링 분석 결과를 얻는다.
③ HTML 파일에 있는 치환문자를 처리하기 위해, String으로 형변환
④ 미리 정의해둔 문자를 POST메서드로
받은 값으로 치환한다.
⑤ 응답 헤더를 쓰고,
⑥ 브라우저로, HTML 파일을 보내고 연결을 종료한다.
38. POST 메서드로 들어온, 폼 데이터를 버퍼에 계속 쌓아 둔다.
요청이 끝나면, 버퍼에 쌓아두었던 쿼리스트링을 파싱해 사용하기 편하게 만든다.
HTML 파일을 읽고, 파일에 있던 치환 문자를 파싱된 데이터로 치환한다.
HTTP 메서드에 따라, 폼 값을 받는 형식이 달라진 점에 유의해 봐요.
39. Source : https://ko.wikipedia.org/wiki/HTTP , http://www.w3schools.com/tags/ref_httpmethods.asp
HTTP 메서드에는 총 8가지가 존재하지만, 주로 GET과 POST 메서드를 사용
http://search.naver.com/search.naver?where=nexearch&query=node.js
&sm=top_hty&fbm=1&ie=utf8
POST /test/demo_form.asp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2
GET 메서드의 예
POST 메서드의 예
단순 데이터 조회 할 때는 GET을,
다양의 데이터를 보내거나/브라우저를 통해 데이터 노출을 방지하려고 때는 POST 방식을 사용합니다.
42. 작업할 폴더를 만들고, 해당 폴더에서 다음 명령을 실행하세요.
npm install express
설치가 완료되면, node_modules 폴더가 자동으로 생성되고,
이 폴더에 express 소스 파일들이 다운로드됩니다.
45. 템플릿 엔진으로 EJS를 사용.
앱 폴더에서 아래 명령으로 파일 준비
express --ejs
아래 명령으로 설치 진행
npm install
46. 아래 명령을 통해 앱을 구동
그리고 http://127.0.0.1 으로 접속
47. Express 없이 만들어 봤던, 폼 페이지를 만들어봅니다.
app.js 파일을 열어, 앞서 만든 route 파일을 연결해 줍니다.
routes 에서 지정한 템플릿 파일을 views 폴더에 .ejs 파일 확장자를 붙여 만든다.
* 정적인 콘텐츠는 public 폴더에 두고, 사용합니다.
routes 폴더에 URL을 정의해 둘 JS 파일을 만든다.
48. 이름, 이메일, 하고 싶은 말 등을
입력 할 수 있는 폼을 제공하는
/hello/form 을 만듭니다.
/hello/formSubmit 이라는 주소로,
POST 메서드로 전송하게 하고,
전송 받은 내용을 다시 출력해 봅니다.
49. URL을 정의하고, 어떤 View를 사용할지, 어떤 데이터를 View에서 사용할 수 있도록 할지 정의합니다.
MVC 디자인 패턴에서, Controller에 해당한다고 볼 수 있습니다.
50. require()를 통해 작성한 hello 모듈을 불러오고, 이것을 app.use()를 통해,
/hello 아래에 연결시켜 줍니다.
51. 컨트롤러에서 전달한 변수를 출력 할 때에는 <%=변수명%>으로 작성하면 됩니다.
변수 값에서 < , > , & , “ 등의 값은 각각 < , > , & , " 등으로 치환되는데, (XSS 문제 때문에)
원본 그대로 출력하고 할 때에는, <%-변수명%>으로 작성합니다.