막하는 스터디 첫 번째 만남 node.js
TRANSCRIPT
크롬 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/
Source : https://nodejs.org/en/about/
As an asynchronous event driven framework
비동기이벤트기반프레임워크
Node.js is designed to build scalable network applications
확장성있는네트워크애플리케이션을만들수있도록설계됨
공식 홈페이지의 “DOWNLOADS” 메뉴를 클릭
본인 컴퓨터 시스템 종료에 맞는
“Windows Installer(.msi)”를 다운로드
https://nodejs.org/en/download/
“컴퓨터” 속성 창
“Next” 버튼만 열심히 잘~
파일의인코딩은 UTF-8로저장하세요!
(1) 웹페이지요청
(2) 자료를찾아서응답
클라이언트(client) 서버(server)
일반적으로웹서버는80번 포트를사용
포트번호는 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 : HTTP119 : NNTP (Network News Transfer Protocol) 뉴스 그룹
194 : IRC (Internet Relay Chat)
443 : TLS/SSL 방식의 HTTP
아직은… 정확하게이게뭐고, 저게무엇인지모르겠지만, 일단코드를작성해봅시다.
네트워크를사용하기때문에, 윈도우방화벽설정창이최초에한번뜹니다. “액세스허용"해줍시다.
* 이창이유지되고있는동안, webserver.js 라는파일이실행되어, 웹서버가작동하게됩니다.
웹브라우저를띄우고, “http://127.0.0.1”로접속
Source : https://ko.wikipedia.org/wiki/루프백
루프백(loop-back) 주소로, 자기자신으로접속하는주소
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번포트로수신대기
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번포트로접속했다
HTML 문서이고, utf-8 문서라고알려준다.
(MIME 타입지정하기)
“안녕, 세계”라고응답하고접속을끊는다.
이러한과정을통해, 방금확인한결과가나온것인데,
따라서, http://127.0.0.1/ 뒤에어떠한문자를붙이더라도항상 “안녕, 세계”가화면에출력될것입니다.
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
추가된부분이무엇인지보이죠? 추가된부분을더작성해봅시다.
http://127.0.0.1/hello/[email protected] 으로접속해보세요.
사실, 어떠한주소로접속해도관계없습니다. 결과를확인하기위한것이니깐요…
Source : https://nodejs.org/api/url.html#url_url_parsing
Uniform Resource Locator
http://127.0.0.1/hello/[email protected]#sadang
protocol
host
pathname
search
query (query string)
hash
127.0.0.1:80
hostname port
var url = require('url');
var oUrl = url.parse(req.url);
res.writeHead(200, { 'Content-Type' : 'text/html;charset=utf-8' });
res.write("req.url : " + req.url );
res.write("<hr />");
res.write("pathname : " + oUrl.pathname + "<br />");
res.write("query : " + oUrl.query + "<br />");
res.write("<hr />");
res.end('안녕, 세계');
① url 모듈획득
② URL문자열을파싱
③ URL 전체확인용
④파싱된 pathname
⑤파싱된 query
URL 모듈을통해, URL 문자열을파싱
파싱과정을통해, URL 요소별로값획득이용이해짐.
사용자가접속했다는것외에, 어떠한주소로접속을했는지알수있다는것을확인완료!
http://127.0.0.1로접속하면,
webserver.js 파일이있는, 폴더에있는,
index.html 파일을클라이언트에게보내준다.
“이곳”이라는텍스트에http://127.0.0.1/place 로이동하도록링크를걸어두고, /place 로접속하면,
plcae.html 파일을클라이언트에게보내준다.
와… 뭔가… 코드가복잡해보이기시작…
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번포트로수신대기
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 파일이없는경우에는어떻게될까요?
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 파일을읽는다
③읽혀진파일내용으로응답
else
{
res.writeHead(404, {"Content-Type": "text/plain"});
res.end("Page Not Found!!");
}
①정의되지않은 URL로접근시, 404 오류를내려보낸다.
② HTTP 응답코드 404를내려보낸다.
③적절한메시지전달
Source : https://ko.wikipedia.org/wiki/HTTP_상태_코드
HTTP 응답코드라고도하며, 아래와같은주요상태코드를알고있으면도움됨.
200 : 성공
302 : 임시 이동
400 : 서버가 해석하지 못하는 잘 못된 구문을 웹 브라우저가 보낸 경우
401 : 권한 없음. 인증 실패 시
403 : 금지됨. 서버가 요청을 거부함.
404 : 찾을 수 없음. 서버가 요청한 페이지를 찾을 수 없는 경우.
500 : 서버 내부 오류
이름, 이메일, 하고싶은말등을입력할수있는폼을제공하는/form 을만듭니다.
/formSubmit 이라는주소로,
POST 메서드로전송하게하고,
전송받은내용을다시출력해봅니다.
헉… 아까보다더복잡해지기시작…
콜백안에콜백이 …
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 모듈획득
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 파일을읽는다
④읽혀진파일내용으로응답
else if (oUrl.pathname == “/formSubmit”)
{
var arrBuffer = [];
req.on('data', function (postRawData) {
arrBuffer.push( postRawData.toString() );
});
① URL에서 pathname 이 “/formSubmit” 인경우,
②브라우저가보내오는 POST 데이터를수집해둘배열
③데이터가올때마다, arrBuffer 배열에푸시해모아둡니다.
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 파일을보내고연결을종료한다.
POST 메서드로들어온, 폼데이터를버퍼에계속쌓아둔다.
요청이끝나면, 버퍼에쌓아두었던쿼리스트링을파싱해사용하기편하게만든다.
HTML 파일을읽고, 파일에있던치환문자를파싱된데이터로치환한다.
HTTP 메서드에따라, 폼값을받는형식이달라진점에유의해봐요.
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 방식을사용합니다.
작업할폴더를만들고, 해당폴더에서다음명령을실행하세요.
npm install express
설치가완료되면, node_modules 폴더가자동으로생성되고,
이폴더에 express소스파일들이다운로드됩니다.
좀더… 간결하고, 쉽게처리할수있게되었어요.
npm install express-generator –g
Source : http://expressjs.com/starter/generator.html
템플릿엔진으로 EJS를사용.
앱폴더에서아래명령으로파일준비
express --ejs
아래명령으로설치진행
npm install
아래명령을통해앱을구동
그리고 http://127.0.0.1 으로접속
Express 없이만들어봤던, 폼페이지를만들어봅니다.
app.js 파일을열어, 앞서만든 route 파일을연결해줍니다.
routes 에서지정한템플릿파일을 views 폴더에 .ejs 파일확장자를붙여만든다.
* 정적인콘텐츠는 public 폴더에두고, 사용합니다.
routes 폴더에 URL을정의해둘 JS 파일을만든다.
이름, 이메일, 하고싶은말등을입력할수있는폼을제공하는/hello/form 을만듭니다.
/hello/formSubmit 이라는주소로,
POST 메서드로전송하게하고,
전송받은내용을다시출력해봅니다.
URL을정의하고, 어떤 View를사용할지, 어떤데이터를 View에서사용할수있도록할지정의합니다.
MVC 디자인패턴에서, Controller에해당한다고볼수있습니다.
require()를통해작성한 hello 모듈을불러오고, 이것을 app.use()를통해,
/hello 아래에연결시켜줍니다.
컨트롤러에서전달한변수를출력할때에는 <%=변수명%>으로 작성하면됩니다.
변수값에서 < , > , & , “ 등의값은각각 < , > , & , " 등으로치환되는데, (XSS 문제때문에)
원본그대로출력하고할때에는, <%-변수명%>으로 작성합니다.