'JavaScript'에 해당되는 글 10건

  1. Node.js express 모듈 (6)
  2. Node.js 외부 모듈
  3. Node.js http 모듈
  4. Node.js 이벤트
  5. Node.js 기본 내장 모듈 (2)

Node.js express 모듈



  • http 모듈로 웹 서버를 생성하면 굉장히 많은 일을 직접 처리해야 한다.
  • express 모듈은 http 모듈에 여러 기능을 추가해 쉽게 사용할 수 있게 마든 모듈이다.

[ express 설치 ]

$ npm install express



1. 기본 서버

[ 코드 - 모듈 추출 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');

  • express 모듈로 서버를 실행하려면 http 모듈이 필요하다.

[ 코드 - express 모듈을 사용한 서버 생성 및 실행 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//request 이벤트 리스터를 설정한다.
app.use(function (request, response) {
    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.end('<h1>Hello express</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});


[ 실행 - express 모듈을 사용한 서버 ]


2. 기본 응답 메서드

app.use(function (request, response) {

    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.end('<h1>Hello express</h1>');
});
  • request 이벤트 리스너의 매개변수에는 request 객체와 response 객체가 들어간다.
  • express 모듈로 서버를 생성하면 request 객체와 response 객체에 다양한 기능이 추가된다.

[ response 객체의 메서드 ]
  • response.send() : 매개변수의 자료형에 따라 적절한 형태로 응답한다.
  • response.json() : JSON 형태로 응답한다.
  • response.jsonp() : JSONP 형태로 응답한다.
  • response.redirect() : 웹 페이지 경로를 강제로 이동한다.


[ send() 메서드의 매개변수 ]

  • 문자열 : HTML
  • 배열 : JSON
  • 객체 : JSON
  • 매개변수의 자료형에 따라 적절한 형태로 응답한다.

[ 코드 - send() 메서드 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');


//서버를 생성한다.

var app = express();


//request 이벤트 리스너를 설정한다.

app.use(function (request, response) {

    //데이터를 생성한다.

    var output = [];

    for (var i = 0; i < 3; i++) {

        output.push({

            count: i,

            name: 'name - ' + i

        })

    }


    //응답한다.

    response.send(output);

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});


[ 실행 - send() 메서드를 사용한 JSON 전달 ]

  • send() 메서드에 자바스크립트 객체를 입력했으므로 JSON 형식으로 출력된다.
[ 코드 - 404 코드 전달 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response, next) {
    //응답한다.
    response.send(404, '<h1>ERROR</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});


[ 실행 - send() 메서드를 사용한 오류 전달 ]


[ 실행 - 개발자 도구를 통해 확인 ]

  • 사파리 브라우저에서 제공하는 [ 개발자용 > 웹 속성 보기 ]를 통하여 상태가 404 임을 확인할 수 있다.
  • IE나 크롬에서도 개발자 도구를 통해 네트워크 상태를 확인할 수 있다.

3. 기본 요청 메서드
[ request 객체의 메소드 ]
  • header() : 요청 헤더의 속성을 지정 또는 추출한다.
  • accepts() : 요청 헤더의 Accept 속성을 확인한다.
  • param() : 요청 매개변수를 추출한다.
  • is() : 요청 헤더의 Content-Type 속성을 확인한다.

3.1 요청 헤더의 속성 추출
  • header() 메서드를 사용하면 쉽게 요청 헤더의 속성을 지정하거나 추출할 수 있다.

[ 코드 - User-Agent 속성 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response) {
    //User-Agent 속성을 추출한다.
    var agent = request.header('User-Agent');

    console.log(request.headers);
    console.log(agent);

    //응답한다.
    response.send(200);
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - User-Agent 속성 ]

  • 웹 브라우저에 http://127.0.0.1:52273 에 들어가면 터미널에서 웹 브라우저의 헤더 정보를 볼 수 있다.

[ 코드 - User-Agent 속성에 따른 응답 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response) {
    //User-Agent 속성을 추출한다.
    var agent = request.header('User-Agent');

    //브라우저를 구분한다.
    if (agent.toLowerCase().match(/chrome/)) {
        //페이지를 추출한다.
        response.send('<h1>Hello Chrome .. !</h1>');
    } else {
        //페이지를 출력한다.
        response.send('<h1>Hello express .. !</h1>');
    }
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});
  • 헤더의 속성을 추출하여 브라우저가 크롬인지 확인할 수 있다.
[ 실행 - 크롬으로 접속 ]


[ 실행 - 사파리로 접속 ]



3.2 요청 매개변수 추출
[ 코드 - param() 메서드를 사용한 요청 매개변수 추출 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response) {
    //변수를 선언한다.
    var name = request.param('name');
    var region = request.param('region');

    //응답한다.
    response.send('<h1>' + name + '-' + region + '</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - param() 메서드를 사용한 요청 매개변수 추출 ]

  • http://127.0.0.1:52273/?name=rint&region=seoul 로 접속한 화면이다. name과 region 매개변수 값을 출력한다.

4 미들웨어 개요
  • http 모듈과 express 모듈의 가장 큰 차이점은 바로 request 이벤트 리스너를 연결하는데 use() 메서드를 사용한다는 점이다.
  • use() 메서드는 여러 번 사용할 수 있다.
  • use() 메서드의 매개변수에는 function (request, response, next) { } 형태의 함수를 입력한다.
  • 매개변수 next는 다음에 위치하는 함수를 의미한다.
[ 코드 - 미들웨어 ]
//모듈을 사용한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어 설정(1)
app.use(function (request, response, next) {
    console.log('첫 번째 미들웨어');
    next();
});

//미들웨어 설정(2)
app.use(function (request, response, next) {
    console.log('두 번째 미들웨어');
    next();
});

//미들웨어 설정(3)
app.use(function (request, response, next) {
    console.log('세 번째 미들웨어');

    //응답한다.
    response.writeHead(200, {'content-Type' : 'text/html'});
    response.end('<h1>express Basic</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - 웹 브라우저 출력 ]


[ 실행 - 콘솔 화면 ]

  • use() 메서드의 매개변수로 입력한 함수가 차례대로 실행된다.
  • 요청의 응답을 완료하기 전까지 요청 중간중간에서 여러 가지 일을 처리할 수 있다.
  • 그래서 use() 메서드의 매개변수에 입력하는 함수를 '미들웨어'라고 부른다.

§미들웨어를 사용하는 이유
  • 미들웨어에서 request 객체와 response 객체에 속성 또는 메서드를 추가하면 다음 미들웨어에서 추가한 속성과 메서드를 사용할 수 있다.


[ 코드 - 미들웨어를 사용한 속성 추가 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response, next) {
    //데이터를 추가한다.
    request.number = 52;
    response.number = 273;
    next();
});
app.use(function (request, response, next) {
    //응답한다.
    response.send('<h1>' + request.number + ' : ' + response.number + '</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - 미들웨어를 사용한 속성 추가 ]

  • 미들웨어를 사용하면 특정한 일을 수행하는 모듈을 분리해서 만들 수 있다.

[ express 모듈의 미들웨어 ]
  • logger : 로그 정보를 출력한다.
  • csrf : CSEF 보안을 수행한다.
  • basicAuth : 기본적인 인증을 수행한다.
  • bodyParser : POST 요청 매개변수를 추출한다.
  • cookieParser : 쿠키를 분석한다.
  • session : 세션 처리를 수행한다.
  • methodOverride : 다양한 요청 방식을 수행할 수 있게 한다.
  • responseTime : 응답 시간을 계산한다.
  • router : 페이지 라우트를 수행한다.
  • staticCache : static 미들웨어를 위한 메모리 캐시 층을 생성한다.
  • static : 특정 폴더를 서버의 루트 폴더에 올린다.
  • directory : 서버의 디렉토리 구조를 보여준다.
  • vhost : 가상 호스트를 설정한다.
  • favicon : 파비콘을 생성한다.
  • limit : POST 요청의 데이터를 제한한다.
  • errorHandler : 예외 처리를 수행한다.
  • 미들웨어를 사용하면 다른 사람이 만든 기능을 추가할 수도 있고 자신이 과거에 만든 코드도 재사용하기 편리하다.

5. morgan 미들웨어
  • morgan 미들웨어는 웹 요청이 들어왔을 때 로그를 출력하는 미들웨어이다.
  • express 3.x 버전에서는 express.logger()를 사용했으나 express 4.x 버전부터는 지원하지 않는다. 따라서 morgan 모듈을 설치하여 사용하고자 한다.
[ morgan 모듈 설치 ]
$ npm install morgan

[ 코드 - morgan 미들웨어 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan'); //express 4.x 버전부터는 express.logger()를 지원하지 않으니 morgan 모듈을 설치하여 사용한다.

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
//app.use(express.logger()); //express 3.x 용
app.use(morgan('combined')); //express 4.x 용
app.use(function (request, response) {
    response.send('<h1>express Basic</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - morgan 미들웨어 ]


[ morgan 미들웨어의 토큰 ]

  • :req[header]    요청 헤더를 나타낸다.
  • :res[header]    응답 헤더를 나타낸다.
  • :http-version   HTTP 버전을 나타낸다.
  • :response-time  응답 시간을 나타낸다.
  • :remote-addr    원격 주소를 나타낸다.
  • :date[format]   요청 시간을 나타낸다.
  • :method         요청 방식을 나타낸다.
  • :url            요청 URL을 나타낸다.
  • :referrer       이전 URL을 나타낸다.
  • :User-Agent     사용자 에이전트를 나타낸다.
  • :status         상태 코드를 나타낸다.

[ 코드 - morgan 미들웨어의 토큰 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan(':method + :date'));
app.use(function (request, response) {
    response.send('<h1>express Basic</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});
  • 웹 브라우저로 http://127.0.0.1:52273 을 호출할 때마다 콘솔에 :method와 :date 에 대한 메시지가 출력된다.

[ 실행 - morgan 미들웨어 토큰 ]

  • 웹 브라우저로 http://127.0.0.1:52273 을 3번 호출했다.
  • :method 로 GET 요청인지 POST 요청인지 출력한다.
  • :date 로 웹 브라우저로 요청한 시간을 출력한다.


[ morgan 미들웨어의 기본 형식 ]

  • default        :default-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":User-Agent"
  • short          :remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
  • tiny           :method :url :status :res[content-length] - :response-time ms


[ 코드 - morgan 미들웨어 기본 형식 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');

var morgan = require('morgan');


//서버를 생성한다.

var app = express();


//미들웨어를 설정한다.

app.use(morgan('short'));

app.use(function (request, response) {

    response.send('<h1>express Basic</h1>');

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});


[ 실행 - morgan 미들웨어 기본 형식 ]

  • short의 형식인 :remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms 로 출력된다.

6. static 미들웨어
  • static 미들웨어는 웹 서버에서 손쉽게 파일을 제공하는 방법을 제공한다.

[ 코드 - static 미들웨어 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan('combined'));
app.use(express.static(__dirname + '/public'));
app.use(function (request, response) {
    //응답한다.
    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.end('<img src="/Node.js logo.png" width="100%" />');
})

//서버를 실행한다.
http.createServer(app).listen(52273, function() {
    console.log('Server running at http://127.0.0.1:52273');
});
  • public 폴더를 생성하여 그림 파일, 자바스크립트 파일, CSS 파일 등을 넣는다. 여기에서는 그림 파일을 넣었다.
  • 전역변수 __dirname을 사용하여 폴더 위치를 지정하면 나머지는 express 모듈이 전부 알아서 해준다.
  • static 미들웨어를 사용하면 지정한 폴더에 있는 내용을 모두 웹 서버 루트 폴더에 올린다.
  • 따라서 img 태그의 src 속성에 "/public"이 아닌 바로 이미지 파일명을 입력하여 사용했다.
[ 실행 - static 미들웨어 ]

  • 지정한 이미지 파일이 출력된 것을 확인할 수 있다.

7. router 미들웨어
  • router 미들웨어는 페이지 라우팅을 구현하는 미들웨어이다.
  • 페이지 라우팅은 클라이언트 요청에 적절한 페이지를 제공하는 기술이다.
  • app.router 속성을 사용하고 다른 미들웨어와 다르게 express 객체에 들어있는 것이 아니고 함수를 호출하는 것이 아니다.
[ 코드 - router 미들웨어 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan('combined'));
app.use(app.router);

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ app 객체의 메서드 ]
  • get(path, callback)        GET 요청이 발생했을 때의 이벤트 리스너를 지정한다.
  • post(path, callback)       POST 요청이 발생했을 때의 이벤트 리스너를 지정한다.
  • put(path, callback)       PUT 요청이 발생했을 때의 이벤트 리스너를 지정한다.
  • del(path, callback)        DELETE 요청이 발생했을 때의 이벤트 리스너를 지정한다.
  • all(path, callback)        모든 요청이 발생했을 때의 이벤트 리스너를 지정한다.

[ 코드 - app 객체의 메서드 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan('combined'));
//app.use(app.router); //express 4.x 부터 사용되지 않는다. 바로 get() 또는 post()로 사용한다.
app.use(express.static(__dirname + '/public'));

//라우터를 설정한다.
app.get('/a', function (request, response) {
    response.send('<a href="/b">Go to B</a>');
});
app.get('/b', function (request, response) {
    response.send('<a href="/a">Go to A</a>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - router 모듈의 기본적인 사용 결과 ]

  • http://127.0.0.1:52273/a 로 접근했을 때의 화면이다.

  • http://127.0.0.1:52273/b 로 접근했을 때의 화면이다.

  • http://127.0.0.1:52273/a 와 http://127.0.0.1:52273/b 로 접근했을 때 출력된 로그이다.

[ 코드 - router 모듈의 매개변수 추출 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan('combined'));
//app.use(app.router); //express 4.x버전부터 사용하지 않는다.

//라우터를 설정한다.
app.get('/page/:id', function (request, response) {
    //변수를 선언한다.
    var name = request.param('id');

    //응답한다.
    response.send('<h1>' + name + ' Page</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});
  • get() 메서드의 첫 번째 매개변수에 문자열 /:id 를 입력했다.
  • http://127.0.0.1:52273/page/273 에 접속하면 id 속성에 273을 입력했으므로 '273 Page'를 출력한다.
[ 실행 - 매개변수 출력 ]


[ 코드 - 전체 선택자 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
//app.use(app.router); //express 4.x부터 사용되지 않는다.

//라우터를 설정한다.
app.get('/index', function (request, response) {
    response.send('<h1>Index Page</h1>');
});

app.all('*', function (request, response) {
    response.send(404, '<h1>ERROR - Page Not Found</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});
  • http://127.0.0.1:52273/index 이외의 요청은 모두 에러를 출력한다.
[ 실행 - 정상 출력 ]

  • http://127.0.0.1:52273/index 로 접근했을 때의 화면이다.
[ 실행 - 오류 출력 ]

  • http://127.0.0.1:52273/index 이외에 다른 주소로 접근했을 때의 오류 화면이다. ex) http://127.0.0.1:52273/test

8. cookie parser 미들웨어
  • cookie parser 미들웨어는 요청 쿠키를 추출하는 미들웨어이다.
  • cookie parser 미들웨어를 사용하면 request 객체에 cookies 속성이 부여된다.
[ 코드 - cookie parser 미들웨어 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var cookieParser = require('cookie-parser'); //express 4.x부터 express.cookieParser()가 사용되지 않으므로 이것으로 사용한다.

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
//app.use(express.cookieParser()); //express 4.x부터 사용하지 않는다.
//app.use(app.router); //express 4.x부터 사용하지 않는다.
app.use(cookieParser()); //express 4.x부터 express.cookieParser()가 사용되지 않으므로 이것으로 사용한다.

//서버를 실행한다.
http.createServer(app).listen(52273, function (request, response) {
    console.log('Server running at http://127.0.0.1:52273');
});
  • require('cookie-parser') 를 사용하기 위해서는 모듈을 설치해야 한다.
[ cookie-parser 모듈 설치 ]
$ npm install cookie-parser


[ 코드 - cookie parser 미들웨어를 사용한 쿠키 추출 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');

var cookieParser = require('cookie-parser'); //express 4.x부터 express.cookieParser()가 사용되지 않으므로 이것으로 사용한다.


//서버를 생성한다.

var app = express();

//app.use(app.router); //express 4.x부터 사용되지 않는다.

app.use(cookieParser()); //express 4.x부터 express.cookieParser()가 사용되지 않으므로 이것으로 사용한다.


//라우터를 설정한다.

app.get('/getCookie', function (request, response) {

    //응답한다.

    response.send(request.cookies);

});

app.get('/setCookie', function (request, response) {

    //쿠키를 생성한다.

    response.cookie('string', 'cookie');

    response.cookie('json', {

        name: 'cookie',

        property: 'delicious'

    });


    //응답한다.

    response.redirect('/getCookie');

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});

  • http://127.0.0.1:52273/setCookie 로 접속하면 string 쿠키와 json 쿠키를 생성한다.
  • 이어서 redirect로 getCookie로 자동 이동한다.
[ 실행 - cookie parser 미들웨어 ]


[ cookie() 메서드의 세 번째 매개변수 ]
response.cookie('string', 'cookie', {
maxAge: 6000,
secure: true
});

[ cookie() 메서드의 옵션 속성 ]
  • httpOnly : 클라이언트의 쿠키 접근 권한을 지정한다.
  • secure : secure 속성을 지정한다.
  • expires : expires 속성을 지정한다.
  • maxAge : 상대적으로 expires 속성을 지정한다.
  • path : path 속성을 지정한다.


9. body parser 미들웨어

  • POST 요청 데이터를 추출하는 미들웨어이다.
  • body parser 미들웨어를 사용하면 request 객체에 body 속성이 부여된다.
  • express 4.x부터 body parser가 사용되지 않으므로 body-parser 미들웨어를 설치해야 한다.

[ body-parser 미들웨어 설치 ]
$ npm install body-parser


9.1 입력 양식 데이터 추출

[ 코드 - login.html 파일 ]

<!DOCTYPE html>

<html>

<head>

    <title>Login Page</title>

</head>

<body>

    <h1>Login Page</h1>

    <hr />

    <form method="post">

        <table>

            <tr>

                <td><label>Username</label></td>

                <td><input type="text" name="login" /></td>

            </tr>

            <tr>

                <td><label>Password</label></td>

                <td><input type="password" name="password" /></td>

            </tr>

        </table>

        <input type="submit" name="" />

    </form>

</body>

</html>


[ 코드 - 서버 기본 설정 ]

//모듈을 추출한다.

var fs = require('fs');

var http = require('http');

var express = require('express');

var cookieParser = require('cookie-parser');

var bodyParser = require('body-parser');


//서버를 생성한다.

var app = express();


//미들웨어를 설정한다.

app.use(cookieParser());


//라우터를 설정한다.

app.get('/', function (request, response) { });

app.get('/login', function (request, response) { });

app.post('/login', function (request, response) { });


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

})

  • 이어서 GET 방식으로 여청했을 경우 POST 방식으로 요청했을 경우 두 가지로 나누어 GET 방식일 때는 HTML 페이지를 추출하고 POST 방식일 때는 클라이언트가 입력한 아이디와 비밀번호를 확인하여 auth 쿠키를 생성하는 것을 만들어보자.
[ 코드 - 기본적인 로그인 구현 ]
//모듈을 추출한다.
var fs = require('fs');
var http = require('http');
var express = require('express');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(cookieParser());
app.use(bodyParser());

//라우터를 설정한다.
app.get('/', function (request, response) {
    if (request.cookies.auth) {
        response.send('<h1>Login Success</h1>');
    } else {
        response.redirect('/login');
    }
});
app.get('/login', function (request, response) {
    fs.readFile('login.html', function (error, data) {
        response.send(data.toString());
    });
});
app.post('/login', function (request, response) {
    //쿠키를 생성한다.
    var login = request.param('login');
    var password = request.param('password');

    //출력한다.
    console.log(login, password);
    console.log(request.body);

    //로그인을 확인한다.
    if (login == 'rint' && password == '1234') {
        //로그인 성공
        response.cookie('auth', true);
        response.redirect('/');
    } else {
        //로그인 실패
        response.redirect('/login');
    }
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
})

[ 실행 - 로그인 화면 ]

  • Username 과 Password에 아무 글자나 입력하면 다시 로그인 화면으로 돌아온다.
  • Username에 rint 를, password에 1234 를 입력하고 [제출] 버튼을 클릭한다.

[ 실행 - 로그인 성공 화면 ]



9.2 파일 업로드
  • 일반적인 입력 양식은 application/x-www-from-urlencoded 인코딩 방식을 사용한다.
  • 파일은 일반적인 입력 양식 데이터에 비해 용량이 크다. 따라서 웹 브라우저는 파일을 전송할 때 multipart/form-data 인코딩 방식을 사용한다.
  • express 4.x부터 multipart 미들웨어가 제거되어 bodyParser 미들웨어의 multipart 기능이 불가능해졌다.
  • 그렇기 때문에 대체수단으로 connect-multipart 미들웨어를 설치한다.

[ connect-multipart 미들웨어 설치 ]
$ npm install connect-multiparty
 
[ 코드 - HTMLPage.html 파일 ]
<!DOCTYPE html>
<html>
<head>
    <title>Multipart Upload</title>
</head>
<body>
    <h1>File Upload</h1>
    <form method="post" enctype="multipart/form-data">
        <table>
            <tr>
                <td>Comment: </td>
                <td><input type="text" name="comment" /></td>
            </tr>
            <tr>
                <td>File: </td>
                <td><input type="file" name="image" /></td>
            </tr>
        </table>
        <input type="submit" />
    </form>
</body>
</html>
  • 반드시 <form> 태그의 enctype 속성을 "multipart/form-data"로 지정해야 한다.
[ 코드 - 미들웨어 설정 ]
//모듈을 추출한다.
var fs = require('fs');
var http = require('http');
var express = require('express');
var multiparty = require('connect-multiparty'); //express 4.x 부터 express 모듈의 multipart 미들웨어가 제거되었다. 따라서 bodyParser 미들웨어에서 multipart 기능(업로드와 form-data 파싱)이 불가능해져서 이 미들웨어를 설치하여 사용한다.
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(cookieParser());
//app.use(express.limit('10mb')); //express 4.x 부터 사용되지 않는다. 아래 문장처럼 사용할 것.
app.use(bodyParser.json({ limit : '10mb' }));
//app.use(bodyParser({ uploadDir : __dirname + '/multipart' }));
app.use(multiparty({ uploadDir : __dirname + '/multipart' }));
//app.use(app.router); //express 4.x 부터 사용되지 않는다. 바로 get() 또는 post()로 사용한다.

//라우터를 설정한다.
app.get('/', function (request, response) {
    fs.readFile('HTMLPage.html', function (error, data) {
        response.send(data.toString());
    });
});
app.post('/', function (request, response) {
    console.log(request.body);
    console.log(request.files);

    response.redirect('/');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});


[ 실행 - 파일 업로드 ]


[ 실행 - 파일 업로드 ]

  • 업로드한 파일의 정보가 출력된다.

[ 코드 - 파일 이름 변경 및 제거 ]

//모듈을 추출한다.

var fs = require('fs');

var http = require('http');

var express = require('express');

var multiparty = require('connect-multiparty'); //express 4.x 부터 express 모듈의 multipart 미들웨어가 제거되었다. 따라서 bodyParser 미들웨어에서 multipart 기능(업로드와 form-data 파싱)이 불가능해져서 이 미들웨어를 설치하여 사용한다.

var cookieParser = require('cookie-parser');

var bodyParser = require('body-parser');


//서버를 생성한다.

var app = express();


//미들웨어를 설정한다.

app.use(cookieParser());

app.use(multiparty());

app.use(express.static('public'));

//app.use(express.limit('10mb')); //express 4.x 부터 사용되지 않는다. 아래 문장처럼 사용할 것.

app.use(bodyParser.json({ limit : '10mb' }));

app.use(bodyParser({ uploadDir : __dirname + '/multipart' }));

//app.use(app.router); //express 4.x 부터 사용되지 않는다. 바로 get() 또는 post()로 사용한다.


//라우터를 설정한다.

app.get('/', function (request, response) {

    fs.readFile('HTMLPage.html', function (error, data) {

        response.send(data.toString());

    });

});

app.post('/', function (request, response) {

    var comment = request.param('comment');

    var imageFile = request.files.image;


    if (imageFile) {

        //변수를 선언한다.

        var name = imageFile.name;

        var path = imageFile.path;

        var type = imageFile.type;


        //이미지 파일 확인

        if (type.indexOf('image') != -1) {

            //이미지 파일의 경우: 파일의 이름을 변경한다.

            var outputPath = __dirname + '/multipart/' + Date.now() + '_' + name;


            fs.rename(path, outputPath, function (error) {

                response.redirect('/');

            });

        } else {

            //이미지 파일이 아닌 경우: 파일 이름을 제거한다.

            fs.unlink(path, function (error) {

                response.send(400);

            });

        }

    } else {

        //파일이 없을 경우

        response.send(404);

    }

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});

  • 파일 업로드 할 때 파일명이 같은 경우 덮어 씌워지게 된다. 따라서 파일명을 확인하여 중복되지 않도록 하고자 한다.
  • rename() 메서드를 사용해 시간을 기반으로 파일의 이름을 변경한다.(이 방식이 100% 중복을 막을 수 없으나 예제로 하겠다.)
  • 또한 이미지 파일이 아니라면 파일을 제거한다.
  • 웹브라우저로 실행하여 파일을 업로드하면 multipart 디렉터리에 "날짜_파일명.확장자"와 같은 형식으로 이름이 바뀌어 업로드된 것을 확인할 수 있다.


10. session 미들웨어

  • 쿠키(cookie)는 정보를 클라이언트의 PC에 저장하고 세션(session)은 정보를 서버에 저장하는 기술이다.
  • 세션은 클라이언트에 세션 식별자 쿠키를 부여한다.
  • 부여한 세션 식별자 쿠키와 대응되는 서버에 위치하는 별도 저장소에 데이터를 저장한다.
  • session 미들웨어는 세션을 쉽게 생성할 수 있게 도와주는 미들웨어이다.
  • session 미들웨어를 사용하면 request 객체에 session 속성을 부여한다.
  • session 미들웨어는 자체적으로 cookie parser 미들웨어를 사용하므로 cookie-parser 미들웨어와 session 미들웨어가 순서대로 추가되어야 한다.
  • express 4.x부터 express.session()이 지원되지 않으므로 cookie-session 미들웨어를 설치한다.


[ cookie-session 미들웨어 설치 ]

$ npm install cookie-session


[ 코드 - session 미들웨어 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');

var cookieParser = require('cookie-parser');

var session = require('cookie-session');

var bodyParser = require('body-parser');


//서버를 실행한다.

var app = express();


//미들웨어를 설정한다.

app.use(cookieParser());

app.use(session({ secret: 'secret key' }));

app.use(bodyParser());

app.use(function (request, response) {

    //변수를 선언한다.

    var output = {};

    output.cookies = request.cookies;

    output.session = request.session;


    //세션을 저장한다.

    request.session.now = (new Date()).toUTCString();


    //응답한다.

    response.send(output);

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});


[ 실행 - 처음 접속 ]

  • session에 저장된 내용만 출력된다. cookie 정보는 다시 접속했을 때 나타나게 된다.


[ 실행 - 두 번째 접속 ]

  • 다시 접속하면 cookies의 express:sess.sig 쿠키가 생성된 것을 확인할 수 있다. 이것은 쿠키로 서버에 저장된 데이터를 확인한다.
  • 브라우저를 종료하고 다시 실행하면 express:sess.sig 쿠키가 소멸되므로 클라이언트는 자신이 소유한 정보를 잃게 된다.

[ 코드 - session() 메서드의 옵션 ]
  • session의 이름과 유지하는 시간을 바꾸어보자.
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var cookieParser = require('cookie-parser');
var session = require('cookie-session');
var bodyParser = require('body-parser');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(cookieParser());
app.use(session({
    secret: 'secret key',
    key: 'rint',
    cookie: {
        maxAge: 60 * 1000
    }
}));
app.use(bodyParser());
app.use(function (request, response) {
    //변수를 선언한다.
    var output = {};
    output.cookies = request.cookies;
    output.session = request.session;

    //세션을 저장한다.
    request.session.now = (new Date()).toUTCString();

    //응답한다.
    response.send(output);
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});



[ session() 메서드의 옵션 ]

  • key : 쿠키의 name 속성을 지정한다.
  • store : 세션 저장소를 지정한다.
  • cookie : 생성할 cookie와 관련된 정보를 지정한다.


[ cookie 속성을 입력하지 않으면 다음과 같은 객체가 입력된다.

{ path: '/', httpOnly: true, maxAge: null }


[ session 객체의 메서드 ]

  • regenerate() : 세션을 다시 생성한다.
  • destroy() : 세션을 제거한다.
  • reload() : 세션을 다시 불러온다.
  • save() : 세션을 저장한다.



11. RESTful 웹 서비스 개발

  • RESTful 웹 서비스는 REST(REpresentational Status Transfer) 규정에 맞춰 만든 웹 서비스를 의미한다.
  • REST 규정이란?
    • 일관된 웹 서비스 인터페이스 설계를 위한 규정이다.
[ RESTful 웹 서비스의 구조 ]

 경로

 /collection

 collection 

 GET 방식

 컬렉션을 조회한다.

 컬렉션의 특정 요소를 조회한다. 

 POST 방식

 컬렉션에 새로운 데이터를 추가한다.

 사용하지 않는다.

 PUT 방식

 컬렉션 전체를 한꺼번에 변경한다.

 컬렉션에 특정 요소를 수정한다.

 DELETE 방식

 컬렉션 전체를 삭제한다.

 컬렉션의 특정 요소를 삭제한다.


[ 예제 ]
  • GET /user - 사용자 전체를 조회한다.
  • GET /user/273 - 273번 사용자를 조회한다.
  • POST /user - 사용자를 추가한다.
  • DELETE /user/273 - 273번 사용자를 삭제한다.


[ RESTful 웹 서비스 ]

 라우트

 경로

 설명

 GET

 /user

 모든 사용자 정보를 조회한다.

 GET

 /user/:id

 특정 사용자 정보를 조회한다.

 POST

 /user

 사용자를 추가한다.

 PUT

 /user/:id

 특정 사용자 정보를 수정한다.

 DELETE

 /user/:id

 특정 사용자 정보를 제거한다.



[ 코드 - 시작 코드 ]
//모듈을 추출한다.
var fs = require('fs');
var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');

//더미 데이터베이스를 구현한다.
var DummyDB = (function () {

})();

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(bodyParser());

//라우터를 설정한다.
app.get('/user', function (request, response) { });
app.get('/user/:id', function (request, response) { });
app.post('/user', function (request, response) { });
app.put('/user/:id', function (request, response) { });
app.del('/user/:id', function (request, response) { });

//서버를 실행한다.
http.createServer(app).listen(52283, function () {
    console.log('Server running at http://127.0.0.1:52273');
});



11.1 더미 데이터베이스 구현

  • 데이터를 저장하려면 데이터 저장소가 필요하다.
  • 일반적으로 MySQL 같은 데이터베이스를 사용하지만 아직 배우지 않았으므로 더미 데이터베이스라는 가상의 데이터베이스를 만들어서 사용하자.
[ 코드 - DummyDB ]
//더미 데이터베이스를 구현한다.
var DummyDB = (function () {
    //변수를 선언한다.
    var DummyDB = {};
    var storage = {};
    var count = 1;

    //메서드를 구현한다.
    DummyDB.get = function (id) {
        if (id) {
            //변수를 가공한다.
            id = (typeof id == 'string') ? Number(id) : id;

            //데이터를 선택한다.
            for (var i in storage) if (storage[i].id == id) {
                return storage[i];
            }
        } else {
            return storage;
        }
    };

    DummyDB.insert = function (data) {
        data.id = count++;
        storage.push(data);
        return data;
    };

    DummyDB.remove = function (id) {
        //변수를 가공한다.
        id = (typeof id == 'string') ? Number(id) : id;

        //제거한다.
        for (var i in storage) if (storage[i].id == id) {
            //데이터를 제거한다.
            storage.splice(i, 1);

            //리턴한다 : 데이터 삭제 성공
            return true;
        }

        //리턴한다 : 데이터 삭제 실패
        return false;
    };

    //리턴한다.
    return DummyDB;
})();

  • get() 메서드
    • 데이터를 조회하는 메서드이다.
    • 매개변수 id를 넣고 호출하면 특정 데이터 하나를 선택해서 리턴한다.
    • 반면 id를 넣지 않고 호출하면 모든 데이터를 리턴한다.
  • insert() 메서드
    • 데이터를 추가하는데 사용한다.
    • 데이터에 id 속성을 추가하고 storage 배열에 넣는다.
    • 모든 처리가 정상적으로 완료되면 자기 자신을 리턴한다.
  • remove() 메서드
    • 데이터를 제거하는 메서드이다.
    • 배열의 splice() 메서드를 사용해 특정 데이터를 제거한다.


11.2 GET 요청

[ 코드 - GET 요청 ]

app.get('/user', function (request, response) {

    response.send(DummyDB.get());

});

app.get('/user/:id', function (request, response) {

    response.send(DummyDB.get(request.param('id')));

});

  • 모든 사용자를 조회하는 것과 특정 사용자를 조회하는 것을 구현한 것이다.
  • http://127.0.0.1:52273/user 에 접속한다. 아직 데이터를 넣지 않았으므로 아무 데이터도 출력되지 않는다.

11.3 POST 요청

[ 코드 - POST 요청 ]

app.post('/user', function (request, response) {

    //변수를 선언한다.

    var name = request.param('name');

    var region = request.param('region');


    //유효성을 검사한다.

    if (name && region) {

        response.send(DummyDB.insert({

            name: name,

            region: region

        }));

    } else {

        throw new Error('error');

    }

});

  • 입력 양식으로부터 전달된 name 속성과 region 속성을 추출하고 더미 데이터베이스에 추가한다.

[ 실행 - POST 요청 ]


  • 크롬 확장프로그램인 Postman 으로 실행한 모습이다.
  • 어떤 이유인지는 알 수 없으나 [form-data]로 하면 에러가 발생된다. 이부분 때문에 몇일동안 검색도 많이 해봤으나 해결하진 못했다.
  • [x-www-form-urlencoded]로 선택하여 진행하면 정상적으로 나온다. 파라미터 값에 한글을 입력한 것도 아닌데 왜 urlencode로 넘겨야 정상적으로 작동하는 것인지 이유는 모르겠다. ㅜ_ㅜ;;;
  • name, region, id 값이 정상적으로 DummyDB에 등록되어 화면에 출력된 모습을 볼 수 있다.

11.4 PUT 요청

  • id 속성과 name 속성, region 속성을 추출하고 더미 데이터베이스에서 데이터를 추출해 수정한다.
[ 코드 - PUT 요청 ]
app.put('/user/:id', function (request, response) {
    //변수를 선언한다.
    var id = request.param('id');
    var name = request.param('name');
    var region = request.param('region');

    //데이터베이스를 수정한다.
    var item = DummyDB.get(id);
    item.name = name || item.name;
    item.region = region || item.region;

    //응답한다.
    response.send(item);
});



[ 실행 - PUT 요청 ]


  • 앞서 POST 요청에서처럼 테스트한 뒤 PUT 요청을 사용하여 DummyDB를 수정해본다.

11.5 DELETE 요청
[ 코드 - DELETE 요청 ]
app.del('/user/:id', function (request, response) {
    response.send(DummyDB.remove(request.param('id')));
});


[ 실행 - DELETE 요청 ]

  • id가 1인 데이터에 대해 삭제를 하였다.




'Programming > Node.js' 카테고리의 다른 글

Node.js express 4.x 프레임워크 설치 및 실행  (0) 2016.02.11
Node.js express 모듈  (6) 2015.01.25
Node.js 외부 모듈  (0) 2014.11.12
Node.js http 모듈  (0) 2014.11.05
Node.js 이벤트  (0) 2014.07.06
Node.js 기본 내장 모듈  (2) 2014.06.29

Node.js 외부 모듈


  • 일반 개발자가 만들어 배포한 외부 모듈을 사용하고자 한다.
  • Node.js는 npm(Node Package Manager)을 기반으로 모듈을 공유한다.

[ 외부 모듈 설치 ]
$ npm install 모듈명
  • npm을 활용해 ejs 모듈, jade 모듈처럼 웹과 관련된 모듈을 살펴보자
  • 아래와 같이 콘솔 화면에 다음 명령을 입력한다.
$ npm install ejs
$ npm install jade


[ 코드 - 외부 모듈의 사용 ]

//모듈을 추출한다.

var ejs = require('els');

var jade = require('jade');



1. ejs 모듈

[ ejs 모듈 설치 ]

$ npm install ejs

  • 콘솔에서 명령어를 입력하여 설치한다.
  • npm이 자동으로 외부 모듈을 다운로드하고 설치한다.
[ 실행 - ejs 설치 ]


[ 코드 - ejs 모듈 추출 ]

//모듈을 추출한다.

var ejs = require('els');

  • 내장 모듈 추출하는 방법과 동일하다.

§ ejs 모듈이란?
  • 템플릿 엔진 모듈이다.
  • 템플릿 엔진 모듈이란?
    • 특정 형식의 문자열을 HTML 형식의 문자열로 변환하는 모듈을 의미.


1.1 ejs 모듈의 메서드

  • ejs 페이지를 HTML 페이지로 바꾸어 제공하는 서버를 만들어보자.

[ ejs 모듈의 메서드 ]

  • render(string[, option]) : ejs 문자열을 HTML 문자열로 변경한다.


[ 코드 - ejs 모듈을 사용한 웹 페이지 제공 ]

//모듈을 추출한다.

var http = require('http');

var fs = require('fs');

var ejs = require('ejs');


//서버를 생성하고 실행한다.

http.createServer(function (request, response) {

    //ejsPage.ejs 파일을 읽는다.

    fs.readFile('ejsPage.ejs', 'utf8', function (error, data) {

        response.writeHead(200, {'Content-Type' : 'text/html'});

        response.end(ejs.render(data));

    });

}).listen(52273, function () {

    console.log('Server Running at http://127.0.0.1:52273');

});

※ 꼭 인코딩해서 ejs 파일을 읽어야 한다.


[ 실행 - ejs 모듈을 사용한 웹 페이지 제공 ]

  • ejsPage.ejs 파일에 아무런 내용도 입력하지 않았기 때문에 빈 페이지로 제공한다.
1.2 ejs 파일 형식
  • 얼핏 보면 HTML 페이지와 차이점을 느끼지 못할 수 있지만 HTML 형식에서 살펴볼 수 없는 특수한 태그와 그 안에 자바스크립트 코드가 들어있는 것을 확인할 수 있다.
[ ejs 파일의 특수 태그 ]
  • <% Code %> : 자바스크립트 코드를 입력한다.
  • <%= value %> : 데이터를 출력한다.
  • 이 두가지 특수 태그는 render() 메서드를 사용하여 ejs 페이지를 HTML 페이지로 변환할 때 적절한 형태로 변환된다.

[ 코드 - ejsPage.ejs 파일 ]

<% var name = 'RintIanTta'; %>

<h1><%= name %></h1>

<p><%= 52 * 273 %></p>

<hr/>

<% for (var i = 0; i < 10; i++) { %>

    <h2>The Square of <%= i %> is <%= i * i %></h2>

<% } %>


[ 실행 - ejs 모듈을 사용한 웹 페이지 제공 ]


[ 소스 보기 ]

  • 웹 페이지를 소스보기하면 아래와 같이 ejs 코드가 HTML 코드로 변환된 것을 볼 수 있다.

<h1>RintIanTta</h1>
<p>14196</p>
<hr/>

<h2>The Square of 0 is 0</h2>

<h2>The Square of 1 is 1</h2>

<h2>The Square of 2 is 4</h2>

<h2>The Square of 3 is 9</h2>

<h2>The Square of 4 is 16</h2>

<h2>The Square of 5 is 25</h2>

<h2>The Square of 6 is 36</h2>

<h2>The Square of 7 is 49</h2>

<h2>The Square of 8 is 64</h2>

<h2>The Square of 9 is 81</h2>



1.3 데이터 전달

  • ejs 페이지에 데이터를 전달하는 방법을 알아보자.
  • js 코드에서 render() 메서드의 두 번째 매개변수에 전달하고자 하는 데이터를 입력하면 된다.
[ 코드 - ejs 모듈을 사용하는 웹 페이지 제공 ]
//모듈을 추출한다.
var http = require('http');
var fs = require('fs');
var ejs = require('ejs');

//서버를 생성하고 실행한다.
http.createServer(function (request, response) {
    //ejsPage.ejs 파일을 읽는다.
    fs.readFile('ejsPage.ejs', 'utf8', function (error, data) {
        response.writeHead(200, { 'Content-Type' : 'text/html' });
        response.end(ejs.render(data, {
            name : 'RintIanTta',
            description : 'Hello ejs With Node.js .. !'
        }));
    });
}).listen(52273, function () {
    console.log('Server Running at http://127.0.0.1:52273');
});
  • ejs 페이지에 name 속성과 description 속성을 전달한다.
[ 코드 - ejsPage.ejs 파일 ]
<h1><%= name %></h1>
<p><%= description %></p>
<hr />
<% for (var i = 0; i < 10; i++) { %>
    <h2>The Square of <%= i %> is <%= i * 10 %></h2>
<% } %>
  • Node.js 코드에서 전달한 name과 description 변수가 출력된다.
[ 실행 - ejs 모듈을 사용한 웹 페이지 ]

  • ejs 모듈과 같은 템플릿 엔진은 동적 웹 페이지를 생성할 때 사용한다.

2. jade 모듈
  • 템플릿 엔진 모듈
[ jade 모듈 설치 ]

$ npm install jade


2.1 jade 모듈의 메서드

[ jade 모듈의 메서드 ]

complie(string) : jade 문자열을 HTML 문자열로 바꿀 수 있는 함수를 생성한다.


[ 코드 - jade 페이지를 HTML 페이지로 변환 ]

//모듈을 실행한다.

var http = require('http');

var jade = require('jade');

var fs = require('fs');


//서버를 생성하고 실행한다.

http.createServer(function (request, response) {

    //jadePage.jade 파일을 읽는다.

    fs.readFile('jadePage.jade', 'utf8', function (error, data) {

        //jade 모듈을 사용한다.

        var fn = jade.compile(data);


        //출력한다.

        response.writeHead(200, { 'Content-Type' : 'text/html' });

        response.end(fn());

    });

}).listen(52273, function() {

    console.log('Server Running at http://127.0.0.1:52273');

});


2.2 jade 기본 형식

  • 특수한 형태의 HTML 페이지 위에 특수한 태그를 몇 개 추가한 것.
  • 특수한 평태의 HTML. 즉 jade 기본 형식에서 가장 중요한 것은 들여쓰기이다.
[ 코드 - jadePage.jade 파일 - 계층 구조 형성 ]
html
    head
        title
    body
        h1
        h2
        hr
        a

※ 들여쓰기는 탭과 띄어쓰기 중 한 가지 형태만 사용해야 한다. 두 가지 형태를 모두 사용하면 오류가 발생한다.

※ 태그에 속성을 여러 개 입력하고 싶을 때는 쉼표를 사용하여 구분한다.


[  코드 - jadePage.jade 파일 - 속성 및 내용 입력 ]

html

    head

        title Index Page

    body

        h1 Hello jade .. !

        h2 Lorem ipsum

        hr

        a(href="http://blog.movenext.co.kr", data-test="multiple Attribute") Go To MoveNext Blog


[ 실행 - Jade 형식 ]


[ 코드 - jadePage.jade 파일 - 주석 ]

doctype 5

html

    head

        title Index Page

    body

        //JADE String

        h1 Hello jade .. !

        h2 Lorem ipsum

        hr

        a(href="http://blog.movenext.co.kr", data-test="multiple Attribute") Go To MoveNext Blog

  • doctype 5 : <!Doctype html> 로 변환된다.
  • //JADE String : <!--JADE String-->으로 변환된다. (주석 처리)


[ 코드 - jagePage.jade 파일 - div 태그 생성

doctype 5

html

    head

        title Index Page

    body

        //JADE String

        #header

            h1 Hello jade .. !

            h2 Lorem ipsum

        hr

        .article

            a(href="http://blog.movenext.co.kr", data-test="multiple Attribute") Go To MoveNext Blog

  • #header : id 속성이 header인 div 태그를 생성한다.
  • .article : class 속성이 article인 div 태그를 생성한다.

[ 코드 - jade 기본 형식의 script 태그와 style 태그 ]

doctype 5

html

    head

        title Index Page

        style

            * { margin:0px; padding:0px; }

            h1 {

                color:Red;

            }

        script(src="http://code.jquery.com/jquery-1.10.2.js")

        script

            $(document).ready(function () {

                var alpha = 10;

            });

    body

        h1 Index Page

  • style 속성을 정의하는 방법, 외부에 있는 js파일을 가져오는 방법, script를 직접 정의하는 방법을 보여주고 있다.
2.3 jade 특수 기호

- Code : 자바스크립트 코드를 입력한다.

#{value} : 데이터를 출력한다.

= Value : 데이터를 출력한다.


[ 코드 - jade 코드로 전달한 데이터 ]

//모듈을 실행한다.

var http = require('http');

var jade = require('jade');

var fs = require('fs');


//서버를 생성하고 실행한다.

http.createServer(function (request, response) {

    //jadePage.jade 파일을 읽는다.

    fs.readFile('jadePage.jade', 'utf8', function (error, data) {

        //jade 모듈을 사용한다.

        var fn = jade.compile(data);


        //출력한다.

        response.writeHead(200, {'Content-Type' : 'text/html'});

        response.end(fn({

            name : 'RintIanTta',

            description : 'Hello ejs With Node.js .. !'

        }));

    });

}).listen(52273, function() {

    console.log('Server Running at http://127.0.0.1:52273');

});

  • name 속성과 description 속성을 jade 페이지에 전달한다.
[ 코드 - jadePage.jade - jade 코드로 전달한 데이터 ]

doctype html

html

    head

        title Index Page

    body

        //JADE String

        h1 #{name} .. !

        h2= description

        hr

        - for (var i = 0; i < 10; i++) {

            p

                a(href="http://blog.movenext.co.kr") Go To MoveNext Blog #{i}

        - }

  • #{name} : 전달받은 name 속성을 출력한다.
  • = description : 전달받은 description 속성을 출력한다.
  • - Code : 자바스크립트 코드를 입력한다.
[ 실행 - jade 코드로 전달한 데이터 ]


3. 서버 실행 모듈

  • 지금까지 살펴본 모듈은 지역 모듈로 자바스크립트 파일 내부에서 require() 함수로 추출했다.
  • 지급부터 살펴볼 모듈은 전역 모듈로 터미널에서 곧바로 사용할 수 있는 모듈이다.
  • 전역 모듈을 설치할 때는 g 옵션을 사용한다.
[ 전역 모듈 설치 ]
$ npm install -g supervisor
$ npm install -g forever
$ npm install -g express
  • npm install -g supervisor : 설치할 때 에러가 발생하여 터미널에서 root로 로그인하여 설치하니 정상적으로 설치되었다. (Mac)
  • root 계정으로 로그인한 상태가 아니면 sudo 명령어를 이용하면 된다.(아래에 있음)


3.1 supervisor 모듈

  • Node.js 개발을 하다보면 터미널에서 다음 명령어를 지속적으로 반복한다.
[ 터미널 ]
$ node app.js
>> [파일 수정]
>> [Ctrl] + [C]
$ node app.js
>> [파일 수정]
>> [Ctrl] + [C]
$ node app.js
  • 파일을 변경해도실행된 스크립트에 반영되지 않으므로 다시 종료하고 실행하는 것이다.
  • supervisor 모듈은 파일의 변경을 자동으로 인식하고 종료 후에 실행해준다.


[ supervisor 설치 - 리눅스 or 맥 ]

$ sudo npm install -g supervisor

[ sudo ] password for USER: 비밀번호 입력


[ supervisor 설치 - 윈도우 ]

> npm install -g supervisor


[ 터미널 명령어 - supervisor 기본 명령어 보기 ]

$ supervisor


[ 실행 - supervisor 기본 명령어 보기 ]


[ 코드 - supervisor 기본 파일 ]

//모듈을 추출한다.

var http = require('http');


//서버를 생성 및 실행한다.

http.createServer(function (request, response) {

    response.writeHead(200, {'Content-Type' : 'text/html'});

    response.end('<h1>Test - File - 1</h1>');

}).listen(52273, function() {

    console.log('Server Running at http://127.0.0.1:52273');

});

  • 코드를 입력한 뒤 아래의 supervisor 명령어를 사용하여 실행한다.
[ 터미널 명령어 - supervisor 사용하기 ]
$ supervisor test-server.js


[ 실행 - 터미널 명령어 - supervisor 사용하기 ]


[ 실행 - 기본 실행 결과 ]



[ 코드 - 파일 변경 ]

//모듈을 추출한다.

var http = require('http');


//서버를 생성 및 실행한다.

http.createServer(function (request, response) {

    response.writeHead(200, {'Content-Type' : 'text/html'});

    response.end('<h1>Test - File - 2</h1>');

}).listen(52273, function() {

    console.log('Server Running at http://127.0.0.1:52273');

});

  • 파일 내용을 변경하고 저장하면 supervisor 모듈이 서버를 재시작한다.
  • 따라서 http://127.0.0.1:52273 에 들어가면 파일 내용이 변경된 대로 출력된다.
[ 실행 - 파일 변경 후 실행 결과 ]

  • 파일 변경후 서버를 재실행할 필요없이 바로 적용되는 것을 확인할 수 있다.

3.2 forever 모듈
  • Node.js는 단일 스레드 기반의 웹 서비스이므로 예외 하나가 발생해도 웹 서비스가 죽어버린다.
  • 이러한 예외 상황을 대비하고자 만들어진 모듈이 forever 모듈이다.
[ forever 모듈 설치 ]
$ sudo npm install -g forever
[ sudo ] password for USER: 비밀번호 입력

[ 코드 - 간단한 웹 서버 ]
//서버를 생성 및 실행한다.
require('http').createServer(function (request, response) {
    if (request.url == '/') {
        //응답합니다.
        response.write('<!DOCTYPE html>');
        response.write('<html>');
        resopnse.write('<head>');
        resopnse.write('    <title>Forever</title>');
        response.write('</head>');
        response.write('<body>');
        response.write('    <h1>Forever</h1>');
        response.write('</body>');
        response.write('</html>');
        response.end();
    } else {
        //오류를 발생한다.
        error.error.error();
    }
}).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});
  • 사용자가 기본 경로로 접근하면 정상적으로 응답하지만 다른 경로로 접근하면 오류를 발생하도록 하였다.
[ 명령어 - forever 모듈 실행 ]
$ forever start app.js

[ 실행 - forever 모듈로 실행한 웹 서버 ]

  • http://127.0.0.1:52273 에 들어가면 정상적인 웹 페이지를 호출한다.
[ 실행 - 강제 오류 발생 ]

  • http://127.0.0.1:52273/error 에 들어가본다. 루트 경로가 아닌 곳에 접근했으므로 서버에서 예외가 발생해 서버가 죽어버린다.
  • 우리는 forever 모듈로 웹 서버를 실행하였으므로 다시 http://127.0.0.1:52273에 들어가보면 웹 서버가 정상적으로 동작한다.
[ 실행 - 살아 있는 웹 서버 ]

  • http://127.0.0.1:52273에 들어갔을 때 웹 서버가 정상적으로 동작함을 확인할 수 있다.
[ 명령어 - 현재 실행되고 있는 웹 서버를 확인할 때 사용 ]
$ forever list

[ 명령어 - 프로세스 번호로 서버 종료하기 ]

$ forever stop 0

  • forever list 로 현재 실행되고 있는 웹 서버 목록을 볼 때 프로세스 번호도 나온다.
  • forever stop 프로세스번호 : 프로세스 번호를 입력하여 서버를 종료시킬 수 있다.






'Programming > Node.js' 카테고리의 다른 글

Node.js express 4.x 프레임워크 설치 및 실행  (0) 2016.02.11
Node.js express 모듈  (6) 2015.01.25
Node.js 외부 모듈  (0) 2014.11.12
Node.js http 모듈  (0) 2014.11.05
Node.js 이벤트  (0) 2014.07.06
Node.js 기본 내장 모듈  (2) 2014.06.29

Node.js http 모듈



  • http 모듈은 Node.js의 가장 기본적인 웹 모듈이며 HTTP 웹 서버와 클라이언트를 생성하는 것과 관련된 모든 기능을 담당한다.


1. 요청과 응답

  • 일반적으로 많이 알고 있는 요청과 응답에 대한 내용이다.
  • 요청은 클라이언트가 서버로부터 요구하는 것을 말한다.
  • 응답은 서버가 클라이언트로부터 받은 요청에 대한 정보를 제공해주는 것을 말한다.
  • 기초적인 내용이라 내용 생략.

2. server 객체
  • http 모듈에서 가장 중요한 객체는 server 객체이다.
  • http 모듈의 createServer() 메서드를 사용하면 server 객체를 생성할 수 있다.
[ 코드 - 웹 서버 생성과 실행 ]
//모듈을 실행한다.
var http = require('http');

//웹 서버를 생성한다.
var server = http.createServer();

//웹 서버를 실행한다.
server.listen(52273);
  • 서버 객체를 생성하고 52273번 포트를 사용하여 서버를 실행한다.

[ 메서드 - server 객체의 메서드 ]
  • listen(port[, callback]) : 서버를 실행한다.
  • close() : 서버를 종료한다.

[코드 - server 객체의 close() 메서드 ]
//서버를 생성한다.
var server = require('http').createServer();

//서버를 실행한다.
server.listen(52273, function () {
console.log('Server Running at http://127.0.0.1:52273');
});

//10초 후 함수를 실행한다.
setInterval(function () {
//서버를 종료한다.
server.close();
}, 10000);
  • 서버를 실행하여 10초 후 서버를 종료한다.
[ 이벤트 - server 객체의 이벤트 ]
  • request : 클라이언트가 요청할 때 발생하는 이벤트이다.
  • connection : 클라이언트가 접속할 때 발생하는 이벤트이다.
  • close : 서버가 종료될 때 발생하는 이벤트이다.
  • checkContinue : 클라이언트가 지속적인 연결을 하고 있을 때 발생하는 이벤트이다.
  • upgrade : 클라이언트가 HTTP 업그레이드를 요청할 때 발생하는 이벤트이다.
  • clientError : 클라이언트에서 오류가 발생할 때 발생하는 이벤트이다.


[ 코드 - server 객체의 이벤트 ]

//모듈을 추출한다.

var http = require('http');


//server 객체를 생성한다.

var server = http.createServer();


//server 객체에 이벤트를 연결한다.

server.on('request', function() {

console.log('Request On');

});

server.on('connection', function() {

console.log('Connection On');

});

server.on('close', function() {

console.log('Close On');

});


//listen() 메서드를 실행한다.

server.listen(52273);

  • 코드를 실행한 후 웹 브라우저를 사용하여 http://127.0.0.1:52273에 접속한다.
  • 웹 브라우저는 요청했지만 응답이 없으므로 아무것도 출력되지 않을 것이다.
  • 하지만 콘솔 화면을 살펴보면 이벤트가 실행된 것을 확인할 수 있다.
[ 실행 - server 객체의 이벤트 ]


3. response 객체
  • 클라이언트에 웹 페이지를 제공하려면 응답 메시지를 작성해야 한다.
  • 응답 메시지를 작성할 때는 response 객체를 사용한다.
  • response 객체는 request 이벤트 리스너의 두 번째 매개변수로 전달되는 객체이다.

[ 메서드 - response 객체의 메서드 ]
  • writeHead(statusCode, object) : 응답 헤더를 작성한다.
  • end([data], [encoding]) : 응답 본문을 작성한다.

[ 코드 - 간단한 응답 메시지 작성 ]
//웹 서버를 생성하고 실행한다.
require('http').createServer(function (request, response) {
//응답한다.
response.writeHead(200, {'Content-Type': 'text/html'});
response.end('<h1>Hello Web Server with Node.js</h1>');
}).listen(52273, function () {
console.log('Server Running at http://127.0.0.1:52273');
});
  • 코드를 실행한 후 웹 브라우저에서 http://127.0.0.1:52273에 접속한다.

[ 실행 - 간단한 응답 메시지 작성 ]


3.1 File System 모듈을 사용한 HTML 페이지 제공

  • 자바스크립트 파일 위에서 모든 HTML 페이지를 문자열로 작성하는 것은 불가능하다.
  • File System 모듈을 사용하여 서버에 존재하는 HTML 페이지를 클라이언트에 제공한다.

[ 코드 - 서버 생성 및 실행 ]
//모듈을 추출한다.
var fs = require('fs');
var http = require('http');

//웹 서버를 생성하고 실행한다.
http.createServer(function (request, response) {

}).listen(52273, function () {
console.log('Server Running at http://127.0.0.1:52237');
});

[ 코드 - HTML 파일 제공 ]
//모듈을 추출한다.
var fs = require('fs');
var http = require('http');

//웹 서버를 생성하고 실행한다.
http.createServer(function (request, response) {
//HTML 파일을 읽는다.
fs.readFile('HTMLPage.html', function (error, data) {
response.writeHead(200, {'Content-type' : 'text/html'} );
response.end(data);
});
}).listen(52273, function () {
console.log('Server Running at http://127.0.0.1:52273');
});


[ 코드 - HTMLPage.html ]

<!DOCTYPE html>

<html>

<head>

<title>Index</title>

</head>

<body>

<h1>Hello Node.js</h1>

<h2>Test page</h2>

<p>Lorem ipsum dolor sit amet.</p>

</body>

</html>


[ 실행 - HTML 제공 파일 ]

  • HTMLPage.html 파일의 HTML 페이지를 볼 수 있다.

3.2 이미지와 음악 파일 제공

  • 파일을 제공하는 웹 서버를 만들어보겠다.
  • JPG 이미지 파일과 MP3 음악 파일을 준비한다.

[ 코드 - 서버 생성 및 실행 ]

//모듈을 추출한다.

var fs = require('fs');

var http = require('http');


//52273번 포트에 서브를 생성하고 실행한다.

http.createServer(function (request, response) {


}).listen(52273, function () {

console.log('Server Running at http://127.0.0.1:52273');

});


//52274번 포트에 서버를 생성하고 실행한다.

http.createServer(function (request, response) {


}).listen(52274, function() {

console.log('Server Running at http://127.0.0.1:52274');

});

  • 포트 2개를 사용하여 서버를 2개 생성한다.


[ 코드 - 52273번 포트의 이미지 파일 제공 ]

//52273번 포트에 서브를 생성하고 실행한다.

http.createServer(function (request, response) {

//이미지 파일을 읽는다.

fs.readFile('crystalrain.jpg', function (error, data) {

response.writeHead(200, { 'Content-Type' : 'image/jpeg' });

response.end(data);

});

}).listen(52273, function () {

console.log('Server Running at http://127.0.0.1:52273');

});

  • 특정 형식 파일을 제공할 때 가장 중요한 것은 응답 헤더의 Content-Type 속성이다.
  • Content-Type 속성은 MIME 형식을 입력한다. (image/jpeg)
[ 코드 - 52274번 포트의 음악 파일 제공 ]
//52274번 포트에 서버를 생성하고 실행한다.
http.createServer(function (request, response) {
//음악 파일을 읽는다.
fs.readFile('06 Brunch.mp3', function (error, data) {
response.writeHead(200, { 'Content-Type' : 'audio/mp3' });
response.end(data);
});
}).listen(52274, function() {
console.log('Server Running at http://127.0.0.1:52274');
});
  • 응답 헤더의 Content-Type 속성을 'audio/mp3'로 입력한다.
[ 실행 - 서버 실행 ]


[ 실행 - 이미지 파일 제공 ]



[ 실행 - 음악 파일 제공 ]


[ MME 형식의 예 ]

  • text/plain : 기본적인 텍스트
  • text/html : HTML 문서
  • text/css : CSS 문서
  • text/xml : XML 문서
  • image/jpeg : JPG/JPEG 그림 파일
  • image/png : PNG 그림 파일
  • video/mpeg : MPEG 비디오 파일
  • audio/mp3 : MP3 음악 파일

※ 그 외에도 굉장히 많다.


3.3 쿠키 생성

  • 쿠키는 키(key)와 값(value)이 들어 있는 작은 데이터 조각으로 이름, 값, 파기 날짜와 경로 정보를 가지고 있다.
  • 쿠키는 서버와 클라이언트에서 모두 저장하고 사용할 수 있다.
  • 쿠키는 일정 기간 동안 데이터를 저장할 수 있으므로 일정 기간 동안 로그인을 유지하는 웹사이트에 사용한다.
  • response 객체를 사용하면 클라이언트에 쿠키를 할당할 수 있다.
  • 쿠키를 할당할 때는 응답 헤더의 Set-Cookie 속성을 사용한다.
  • Set-Cookie 속성에는 쿠키의 배열을 넣는다.

[ 쿠키의 형태 ]
Name = Value; Expires = 날짜; Domain = 도메인; Path = 경로; Secure

[ 코드 - 쿠키 저장 및 출력 ]
//모듈을 추출한다.
var http = require('http');

//서버를 생성하고 실행한다.
http.createServer(function (request, response) {
//쿠키를 입력한다.
response.writeHead(200, {
'Content-Type' : 'text/html',
'Set-Cookie' : [
'breakfast = toast; Expires = ' + date.toUTCString(),
'dinner = chicken'
]
});

//쿠키를 출력한다.
response.end('<h1>' + request.headers.cookie + '</h1>');
}).listen(52273, function() {
console.log('Server Running at http://127.0.0.1:52273');
});


[ 실행 - 쿠키 저장 및 출력 (1번째 실행) ]

  • 처음 요청을 할 때는 클라이언트가 쿠키를 갖고 있지 않으므로 undefined로 표시된다. (이미 생성되어 있는 쿠키에 대해서만 쿠키 정보를 불러올 수 있다.)
  • 하지만 쿠키 생성이 실행되었으므로 다음에 요청할 때에는 쿠키 정보를 불러올 수 있다.


[ 실행 - 쿠키 저장 및 출력 (2번째 실행) ]

  • 1번째 요청했을 때 쿠키 생성을 했으므로 2번째 요청했을 때에는 쿠키 정보를 불러올 수 있다.


3.4 페이지 강제 이동

[ 코드 - Location 속성을 사용한 페이지 강제 이동 ]

//모듈을 추출한다.

var http = require('http');


//웹 서버를 생성 및 실행한다.

http.createServer(function (request, response) {

    response.writeHead(302, {'Location' : 'http://m.naver.com'});

    response.end();

}).listen(52273, function() {

    console.log('Server Running at http://127.0.0.1:52273');

});


[ 실행 - Location 속성을 사용한 페이지 강제 이동 ]

  • http://127.0.0.1:52273 으로 접속하면 m.naver.com 으로 페이지 강제 이동을 한다.

[ HTTP Status Code 예 ]
  • writeHead() 메서드의 첫 번째 매개변수를 Status Code라 부른다.
  • 위 예제에서 사용된 302는 강제 페이지 이동을 구현할 때 가장 많이 사용된다.
  • 1XX : 처리 중
    ex) 100 Continue
  • 2XX : 성공
    ex) 200 OK
  • 3XX : 리다이렉트
    ex) 300 Multiple Choices
  • 4XX : 클라이언트 오류
    ex) 400 Bad Request
  • 5XX : 서버 오류
    ex) 500 Internal Server Error


4. request 객체

  • server 객체의 request 이벤트가 발생할 때 이벤트 리스터의 첫 번째 매개변수에 request 객체가 들어간다.
  • request 속성을 사용하면 사용자가 요청한 페이지를 적절하게 제공하는 것은 물론 요청 방식에 따라 페이지를 구분할 수 있다.
[ request 객체의 속성 ]
  • method : 클라이언트의 요청 방식을 나타낸다.
  • url : 클라이언트가 요청한 URL을 나타낸다.
  • headers : 요청 메시지 헤더를 나타낸다.
  • trailers : 요청 메시지 트레일러를 나타낸다.
  • httpVersion : HTTP 프로토콜 버전을 나타낸다.


4.1 url 속성을 사용한 페이지 구분

  • 요청 페이지의 URL에 따라 서로 다른 웹 페이지를 제공하는 애플리케이션을 만들어보자.

[ 코드 - index.html 파일 ]

<!DOCTYPE html>

<html>

<head>

    <title>Index</title>

</head>

<body>

    <h1>Hello Node.js _ Index</h1>

    <h2>Author. RintIanTta</h2>

    <hr/>

    <p>Lorem ipsum dolor sit amet</p>

</body>

</html>



[ 코드 - OtherPage.html ]

<!DOCTYPE html>

<html>

<head>

    <title>OtherPage</title>

</head>

<body>

    <h1>Hello Node.js _ OtherPage</h1>

    <h2>Author. RintIanTta</h2>

    <hr/>

    <p>Lorem ipsum dolor sit amet</p>

</body>

</html>


[ 코드 - app.js (페이지 제공) ]

//모듈을 추출한다.

var http = require('http');

var fs = require('fs');

var url = require('url');


//서버를 생성 및 실행한다.

http.createServer(function (request, response) {

    //변수를 선언한다.

    var pathname = url.parse(request.url).pathname;


    //페이지를 구분한다.

    if (pathname == '/') {

        //Index.html 파일을 읽는다.

        fs.readFile('index.html', function (error, data) {

            //응답한다.

            response.writeHead(200, {'Content-Type' : 'text/html'});

            response.end(data);

        })

    } else if (pathname == '/OtherPage') {

        //OtherPage.html 파일을 읽는다.

        fs.readFile('OtherPage.html', function (error, data) {

            //응답한다.

            response.writeHead(200, {'Content-Type' : 'text/html'});

            response.end(data);

        });

    }

}).listen(52273, function() {

    console.log('Server Running at http://127.0.0.1:52273');

});


[ 실행 - http://127.0.0.1:52273 으로 접속했을 때 ]


[ 실행 - http://127.0.0.1:52273/OtherPage 로 접속했을 때 ]

  • URL 에 따른 페이지 구분 하는 것을 확인할 수 있다.

4.2 method 속성을 사용한 페이지 구분
  • GET 요청인지 POST 요청인지에 따른 페이지를 제공하는 것을 하고자 한다.
  • request 객체의 method 속성을 사용하면 요청 방식에 따른 페이지를 쉽게 구분할 수 있다.
[ 코드 - method 속성을 사용한 페이지 구분 ]
//모듈을 추출한다.
var http = require('http');

//모듈을 사용한다.
http.createServer(function (request, response) {
    if (request.method == 'GET') {
        console.log('GET 요청입니다.');
    } else if (request.method == 'POST') {
        console.log('POST 요청입니다.');
    }
}).listen(52273, function() {
    console.log('Server Running at http://127.0.0.1:52273');
});


[ 실행 - method 속성을 사용한 페이지 구분 ]

  • http://127.0.0.1:52273 으로 URL 페이지를 요청하면 GET 방식으로 수행되는 것을 확인할 수 있다.
  • URL을 입력하는 것만으로는 POST 요청을 수행할 수 없다.


4.3 GET 요청 매개변수 추출

[ 코드 - GET 요청 매개변수 추출 ]

//모듈을 추출한다.

var http = require('http');

var url = require('url');


//모듈을 사용한다.

http.createServer(function (request, response) {

    //요청 매개변수를 추출한다.

    var query = url.parse(request.url, true).query;


    //GET 요청 매개변수 출력

    response.writeHead(200, {'Content-Type' : 'text/html'});

    response.end('<h1>' + JSON.stringify(query) + '</h1>');

}).listen(52273, function() {

    console.log('Server Running at http://127.0.0.1:52273');

});

  • url.parse(request.url, true) : true로 입력하면 배열로 파싱한다. 기본값은 false이다.
  • JSON.stringify(query) : 배열을 JSON 문자열로 변환.


[ 실행 - GET 요청 매개변수 추출 ]

  • http://127.0.0.1:52273/?name=rintiantta&region=seoul 로 접속했을 때


4.4 POST 요청 매개변수 추출

  • GET 방식과 달리 POST 방식은 데이터를 더 많이 담을 수 있고 보안 측면에도 좋다.
[ 코드 - HTMLPage.html 파일 ]
<!DOCTYPE html>
<html>
<head>
    <title>Node.js Example</title>
</head>
<body>
    <h1>Send Data With Post Method</h1>
    <form method="post">
        <table>
            <tr>
                <td><label>Data A</label></td>
                <td><input type="text" name="data_a"/></td>
            </tr>
            <tr>
                <td><label>Data B</label></td>
                <td><input type="text" name="data_b"/></td>
            </tr>
        </table>
        <input type="submit"/>
    </fform>
</body>
</html>
  • POST 매개변수를 입력하는 화면이다.
[ 코드 - request.post.js ]
//모듈을 추출한다.
var http = require('http');
var fs = require('fs');

//모듈을 사용한다.
http.createServer(function (request, response) {
    if (request.method == "GET") {
        //GET 요청
        fs.readFile('HTMLPage.html', function (error, data) {
            response.writeHead(200, {'Content-Type' : 'text/html'});
            response.end(data);
        });
    } else if (request.method == 'POST') {
        //POST 요청
        request.on('data', function (data) {
            response.writeHead(200, {'Content-Type' : 'text/html'});
            response.end('<h1>' + data + '</h1>');
        });
    }
}).listen(52273, function () {
    console.log('Server Running at http://127.0.0.1:52273');
});
  • GET 방식으로 접속할 경우 HTMLPage.html 파일을 제공하고 POST 방식으로 접속할 경우 요청 매개변수를 화면에 출력한다.
[ 실행 - GET 요청 ]

  • GET 방식으로 접속할 경우 HTMLPage.html 파일이 출력된다.
  • Data A와 Data B의 입력 양식에 데이터를 입력하고 [제출] 버튼을 클릭한다.


[ 실행 - POST 요청 ]

  • 앞서 입력했던 데이터가 쿼리 문자열 형태로 출력된다. Query String 모듈을 이용하면 분해하여 원하는 대로 사용할 수 있다.
4.5 쿠키 추출
  • 쿠키는 request 객체의 headers 속성 안 cookie 속성에서 추출할 수 있다.
[ 코드 - 쿠키 생성 및 추출 ]
//모듈을 추출한다.
var http = require('http');

//모듈을 사용한다.
http.createServer(function (request, response) {
    //GET COOKIE
    var cookie = request.headers.cookie;

    //SET COOKIE
    response.writeHead(200, {
        'Content-Type' : 'text/html',
        'Set-Cookie' : ['name = RintIanTta', 'region = seoul']
    });

    //응답한다.
    response.end('<h1>' + JSON.stringify(cookie) + '</h1>');
}).listen(52273, function () {
    console.log('Server Running at http://127.0.0.1:52273');
});

[ 실행 - 처음 접속 ]


[ 실행 - 두 번째 이후 접속 ]

  • 저장된 쿠키가 출력된다.

[ 코드 - 쿠키 분해 ]
//모듈을 추출한다.
var http = require('http');

//모듈을 사용한다.
http.createServer(function (request, response) {
    //쿠키를 추출하고 분해한다.
    var cookie = request.headers.cookie;
    cookie = cookie.split(';').map(function (element) {
        var element = element.split('=');
        return {
            key: element[0],
            value: element[1]
        }
    });

    //쿠키를 생성한다.
    response.writeHead(200, {
        'Content-Type' : 'text/html',
        'Set-Cookie' : ['name = RintIanTta', 'region = Seoul']
    });

    //응답한다.
    response.end('<h1>' + JSON.stringify(cookie) + '</h1>');
}).listen(52273, function() {
    console.log('Server Running at http://127.0.0.1:52273');
});
  • 쿠키 값을 split()을 사용하여 ';'로 분해한다.
  • 분해한 값을 다시 '='로 분해한 뒤 key와 value로 구분하여 리턴한다.

[ 실행 -  쿠키 분해 ]

  • 쿠키 값을 key와 value로 분해하여 출력한 화면이다.



'Programming > Node.js' 카테고리의 다른 글

Node.js express 모듈  (6) 2015.01.25
Node.js 외부 모듈  (0) 2014.11.12
Node.js http 모듈  (0) 2014.11.05
Node.js 이벤트  (0) 2014.07.06
Node.js 기본 내장 모듈  (2) 2014.06.29
Node.js 전역 객체  (0) 2014.06.25

Node.js 이벤트


Node.js의 가장 특징적인 부분은 이벤트 기반 비동기 프로그래밍이다.

가장 많이 활용될 부분이므로 주의 깊게 살펴 보아야 한다.



1. 이벤트 연결

[ 코드 ]

<script>

//window 객체에 load 이벤트를 연결한다.

window.addEventListener('load', function() {


});

</script>

  • 일반적으로 사용되는 자바스크립트로 window 객체에 load 이벤트를 연결하는 코드이다.
  • load를 이벤트 이름 또는 이벤트 타입이라고 한다.
  • 매개변수로 입력한 함수를 이벤트 리스너 또는 이벤트 핸들러라고 한다.


[ 코드 ]

//process 객체에 exit 이벤트를 연결한다.

process.addEventListener('exit', function() {


});

  • process 객체에 exit 이벤트를 연결하는 방법이다. window 객체에 연결한 것과 별반 차이가 없다.
  • Node.js는 addEventListener() 메서드보다 이름이 간단한 메서드를 제공한다.


[ 메서드 - 이벤트 연결 메서드 ]

  • on(eventName, eventHandler) : 이벤트를 연결한다.


[ 코드 ]

//process 객체에 exit 이벤트를 연결한다.

process.on('exit', function() {


});

  • addEventListener() 메서드와 사용하는 방법이 동일하다.
[ 코드 - uncaughtException ]
//process 객체에 uncaughtException 이벤트를 연결한다
process.on('uncaughtException', function(error) {

});
  • uncaughtException 이벤트는 예외가 발생할 때 실행되는 이벤트이다.

[ 코드 - 이벤트 연결 ]

//process 객체에 exit 이벤트를 연결한다.

process.on('exit', function() {

console.log('안녕~ Good Bye~ ^_^');

});


//process 객체에 uncaughtException 이벤트를 연결한다.

process.on('uncaughtException', function(error) {

console.log('예외가 발생했다!!!');

});


//2초 간격으로 3번 예외를 발생시킨다.

var count = 0;

var id = setInterval(function() {

//횟수를 증가시킨다.

count++;


//3번 실행하면 타이머를 중지한다.

if (count == 3) { clearInterval(id); }


//예외를 강제로 발생시킨다.

error.error.error();

}, 2000);

  • 이벤트를 연결하고 2초마다 예외를 발생시킨다.
  • 하지만 책의 내용과는 다르게 예외가 발생하면 setInterval() 메서드가 중지되어 반복 실행이 되질 않는다.
  • Mac버전의 문제일지 일반 PC로 테스트 해봐야겠다.


[ 실행 - 이벤트 연결 ]


2. 이벤트 연결 개수 제한

  • Node.js는한 이벤트에 10개가 넘는 이벤트 리스너를 연결할 경우 개발자 실수로 간주한다.
[ 코드 - 이벤트 11개 연결 ]

//이벤트를 연결한다.

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });


[ 실행 - 이벤트 11개 연결 ]

  • 코드를 실행하면 정상적으로 실행되고 종료되지만 경고가 발생한다.
[ 메서드 - 이벤트 연결 개수 제한 메서드 ]
  • setMaxListeners(limit) : 이벤트 리스너 연결 개수를 조절한다.


[ 코드 - 이벤트 연결 개수 제한 메서드 ]

//이벤트 연결 개수 제한을 15개까지 늘린다.

process.setMaxListeners(15);


//이벤트를 연결한다.

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });

process.on('exit', function() { });


[ 실행 - 이벤트 연결 개수 제한 메서드 ]

  • 경고 없이 실행후 종료되었다.
  • 이벤트 리스너를 무한 개 연결하고 싶을 때는 setMaxListeners() 메서드의 매개변수에 0을 입력한다.


3. 이벤트 제거

[ 메서드 - 이벤트 제거할 때 사용되는 메서드 ]

removeListener(eventName, handler) : 특정 이벤트의 이벤트 리스너를 제거한다.

removeAllListeners([eventName]) : 모든 이벤트 리스너를 제거한다.


[ 코드 - 이벤트 제거 ]

//변수를 선언한다.

var onUncaughtException = function (error) {

//출력한다.

console.log("예외가 발생했군 ^_^ 이번에만 봐주겠다 ^_^ .. !");


//이벤트를 제거한다.

process.removeListener('uncaughtException', onUncaughtException);

};


//이벤트를 연결한다.

process.on('uncaughtException', onUncaughtException);


//2초마다 함수를 실행한다.

setInterval(function() {

//예외를 발생시킨다.

error.error.error('^_^');

}, 2000);

  • 코드를 실행하면 2초 후 예외가 발생하고 uncaughtException 이벤트 리스너가 실행된다.
  • 처음에는 "예외가 발생했군 ^_^ 이번에만 봐주겠다 ^_^ .. !"를 출력하고 넘어가지만 두 번째 예외가 발생하면 프로그램이 종료된다.

[ 실행 - 이벤트 제거 ]



[ 메서드 - 이벤트연결 메서드 ]

  • once(eventName, eventHandler) : 이벤트 리스너를 한 번만 연결한다.


[ 코드 - once() 메서드 ]

//이벤트를 연결한다.

process.once('uncaughtException', function(error) {

//출력한다.

console.log("예외가 발생했군 ^_^ 이번에만 봐주겠다 ^_^ .. !");

});


//2초마다 함수를 실행한다.

setInterval(function() {

//예외를 발생시킨다.

error.error.error('^_^');

}, 2000);


5.5 이벤트 생성

Node.js에서 이벤트를 연결할 수 있는 모든 객체는 EventEmitter 객체의 상속을 받는다. 지금까지 살펴본 process 객체도 EventEmitter 객체의 상속을 받기 때문에 이벤트를 연결할 수 있는 것이다.

EventEmitter 객체는 process 객체 안에 있는 생성자 함수로 생성할 수 있는 객체이다.


[ 메서드 - EventEmitter 객체의 메서드 ]

  • addEventListener(eventName, eventHandler) : 이벤트를 연결한다.
  • on(eventName, eventHandler) : 이벤트를 연결한다.
  • setMaxListeners(limit) : 이벤트 연결 개수를 조절한다.
  • removeListener(eventName, handler) : 특정 이벤트의 이벤트 리스너를 제거한다.
  • removeAllListeners([eventName]) : 모든 이벤트 리스너를 제거한다.
  • once(eventName, eventHandler) : 이벤트를 한 번만 연결한다.


[ 코드 - EventEmiiter 객체 생성 ]

//EventEmitter 객체를 생성한다.

var custom = new process.EventEmitter();


[ 코드 - EventEmitter 객체의 메서드 ]

//EventEmitter 객체를 생성한다.

var custom = new process.EventEmitter();


//이벤트를 연결한다.

custom.on('tick', function() {

console.log('이벤트를 실행합니다. ^_^');

});


//이벤트를 강제로 발생시킨다.

custom.emit('tick');

  • 이벤트를 연결하고 이벤트를 강제로 실행한다.


[ 실행 - EventEmitter 객체의 메서드 ]



§ 이벤트를 생성하는 부분과 연결하는 부분을 모듈로 분리해 사용해보자.

  • rint.js 파일과 app.js 파일을 생성한다. app.js파일은 프로그램 본체가 될 부분이고, rint.js 파일은 이벤트를 생성할 모듈 파일이다.

[ 코드 - rint.js ]

//EventEmitter 객체를 생성한다.

exports.timer = new process.EventEmitter();


//이벤트를 강제로 발생시킨다.

setInterval(function() {

exports.timer.emit('tick');

}, 1000);

  • 모듈을 추출하고 tick 이벤트를 연결한다.

[ 코드 -  app.js ]

//모듈을 추출한다.

var rint = require('./rint');


//이벤트를 연결한다.

rint.timer.on('tick', function() {

console.log('이벤트를 실행한다. ^_^');

});

  • rint.js 파일에서 setInterval() 함수를 실행하여 이벤트를 강제 발생시키므로 app.js 파일에서 연결한 이벤트 리스너를 실행하는 것이다.

[ 실행 ]


'Programming > Node.js' 카테고리의 다른 글

Node.js 외부 모듈  (0) 2014.11.12
Node.js http 모듈  (0) 2014.11.05
Node.js 이벤트  (0) 2014.07.06
Node.js 기본 내장 모듈  (2) 2014.06.29
Node.js 전역 객체  (0) 2014.06.25
맥에서 Node.js 설치하기  (0) 2014.06.23

Node.js 기본 내장 모듈



Node.js는 다양한 모듈을 지원한다. 그래서 모든 모듈을 외운다는 것은 거의 불가능하다.

이에 Node.js 문서를 보고 모듈을 사용하는 방법을 알아보자.


Node.js 문서 : http://nodejs.org/api/



1. os 모듈

  • 운영체제 관련한 모듈을 사용할 수 있다.
  • os 모듈을 사용하려면 require('os')를 사용해야 한다.

[ 코드 ]
//모듈 추출
var os = require('os');

[ 메서드 ]

  • hostname() : 운영체제의 호스트 이름을 리턴한다.
  • type() : 운영체제의 이름을 리턴한다.
  • platform() : 운영체제의 플랫폼을 리턴한다.
  • arch() : 운영체제의 아키텍처를 리턴한다.
  • release() : 운영체제의 버전을 리턴한다.
  • uptime() : 운영체제가 실행된 시간을 리턴한다.
  • loadavg() : 로드 에버리지 정보를 담은 배열을 리턴한다.
  • totalmem() : 시스템의 총 메모리를 리턴한다.
  • freemem() : 시스템의 사용 가능한 메모리를 리턴한다.
  • cpus() : CPU의 정보를 담은 객체를 리턴한다.
  • getNetworkInterfaces() : 네트워크 인터페이스의 정보를 담은 배열을 리턴한다.


[ 코드 ]

//모듈을 추출한다.

var os = require('os');


//모듈을 사용한다.

console.log(os.hostname());

console.log(os.type());

console.log(os.platform());

console.log(os.arch());

console.log(os.release());

console.log(os.uptime());

console.log(os.loadavg());

console.log(os.totalmem());

console.log(os.freemem());

console.log(os.cpus());

console.log(os.getNetworkInterfaces());


[ 실행 ]


2. url 모듈

  • url 관련 한 모듈을 사용할 수 있다.
  • url 모듈을 사용하려면 require('url')을 사용해야 한다.

[ 코드 ]

//모듈을 추출한다.

var url = require('url');


[ 메서드 ]

  • parse(urlStr, [, parseQueryString=false, slashesDenoteHost=false]) : URL 문자열을 URL 객체로 변환해 리턴한다.
  • format(urlObj) : URL 객체를 URL 문자열로 변환해 리턴한다.
  • resolve(from, to) : 매개변수를 조합하여 완전한 URL 문자열을 생성해 리턴한다.


[ 코드 ]

//모듈을 추출한다.

var url = require('url');


//모듈을 사용한다.

var parsedObject = url.parse('http://search.naver.com/search.naver?sm=tab_hty.top&where=nexearch&ie=utf8&query=node.js&x=0&y=0');

console.log(parsedObject);


[ 실행 ]



3. Query String 모듈

  • URL객체의 쿼리와 관련된 모듈이다.

[ 코드 ]

//모듈을 추출한다.

var querystring = require('querystring');


[ 메서드 ]

  • stringify(obj[, sep='&', eq='=']) : 쿼리 객체를 쿼리 문자열로 변환해 리턴한다.
  • parse(str[, sep='&', eq='=']) : 쿼리 문자열을 쿼리 객체로 변환해 리턴한다.


[ 코드 ]

//모듈을 추출한다.

var url = require('url');

var querystring = require('querystring');


//모듈을 사용한다.

var parsedObject = url.parse('http://search.naver.com/search.naver?sm=tab_hty.top&where=nexearch&ie=utf8&query=node.js&x=0&y=0');

console.log(querystring.parse(parsedObject.query));


[ 실행 ]



4. util 모듈

  • node.js의 보조적인 기능을 모아둔 모듈이다.


[ 코드 ]

//모듈을 추출한다.

var util = require('util');


[ 메서드 ]

  • format() : 매개변수로 입력한 문자열을 조합해 리턴한다.

※ console.log() 메서드와의 차이점은 출력하지 않고 문자열을 반환하는 것이다.


[ 코드 ]

//모듈을 추출한다.

var util = require('util');


//모듈을 사용한다.

var data = util.format('%d + %d = %d', 52, 273, 52 + 273);

console.log(data);


[ 실행 ]


5. crypto 모듈

  • 해시 생성과 암호화를 수행하는 모듈이다.
  • 해시는 다른 문자열이라도 같게 나올 수 있다. 따라서 해시를 원래 값으로 되돌리는 것은 완전히 불가능하다.
[ 코드 ]
//모듈을 추출한다.
var crypto = require('crypto');


[ 코드 - 해시 생성 ]

//모듈을 추출한다.

var crypto = require('crypto');


//해시를 생성한다.

var shasum = crypto.createHash('sha1');

shasum.update('crypto_hash');

var output = shasum.digest('hex');


//출력한다.

console.log('crypt_hash:', output);


[ 실행 - 해시 생성 ]


[ 코드 - 암호화 ]

//모듈을 추출한다.

var crypto = require('crypto');


//변수를 선언한다.

var key = 'test'; //아무도 알지 못하는 나만의 비밀 키를 입력한다.

var input = 'PASSWORD'; //암호화할 문자


//암호화

var cipher = crypto.createCipher('aes192', key);

cipher.update(input, 'utf8', 'base64');

var cipheredOutput = cipher.final('base64');


//암호화 해제

var decipher = crypto.createDecipher('aes192', key);

decipher.update(cipheredOutput, 'base64', 'utf8');

var decipheredOutput = decipher.final('utf8');


//출력한다.

console.log('원래 문자열: ' + input);

console.log('암호화: ' + cipheredOutput);

console.log('암호화 해제: ' + decipheredOutput);


[ 실행 - 암호화 ]


6. File System 모듈

  • 파일 처리에 관련된 모듈이다.
[ 코드 ]
//모듈을 추출한다.
var fs = require('fs');


[ 메서드 ]

  • readFile(file, encoding, callback) : 파일을 비동기적으로 읽는다.
  • readFileSync(file, encoding) : 파일을 동기적으로 읽는다.
  • writeFile(file, data, encoding, callback) : 파일을 비동기적으로 쓴다.
  • writeFileSync(file, data, encoding) : 파일을 동기적으로 쓴다.


※ 예제를 시작하기 전에 "textfile.txt" 파일을 만들어 간단한 내용을 입력하여 저장한다.


6.1 파일 읽기

6.1.1 readFileSync()

  • 매개변수에 파일 경로와 인코딩 방식을 지정한다.
[ 코드 ]
//모듈을 추출한다.
var fs = require('fs');

//모듈을 사용한다.
var text = fs.readFileSync('textfile.txt', 'utf8');
console.log(text);


[ 실행 ]


6.1.2 readFile()

  • readFileSync() 메서드를 비동기적으로 구현한 메서드이다.
  • readFile() 메서드를 만나는 순간 이벤트 리스너를 등록하고 파일을 모두 읽으면 이벤트 리스너를 실행한다.
  • 파일을 정상적으로 읽으면 콜백 함수의 두 번째 매개변수에 읽은 데이터를 전달한다.
[ 코드 ]
//모듈을 추출한다.
var fs = require('fs');

//모듈을 사용한다.
fs.readFile('textfile.txt', 'utf8', function (error, data) {
console.log(data);
});


[ 실행 ]


6.2 파일 쓰기

  • writeFile() 메서드와 writeFileSync() 메서드를 사용하는 예제를 보겠다.
[ 코드 ]
//모듈을 추출한다.
var fs = require('fs');

//변수를 선언한다.
var data = "Hello World .. !";

//모듈을 사용한다.
fs.writeFile('TextFileOtherWrite.txt', data, 'utf8', function (error) {
console.log('WRITE FILE ASYNC COMPLETE');
});

fs.writeFileSync('TextFileOtherWriteSync.txt', data, 'utf8');
console.log('WRITE FILE SYNC COMPLETE');


[ 실행 ]


6.3 예외 처리

  • 파일을 읽고 쓰는 일은 굉장히 위험한 일이다. 파일을 읽으려고 하는데 파일이 존재하지 않을 경우 프로그램은 예외가 발생해 곧바로 종료된다.
  • 또한 파일을 쓸 수 없는 위치에 파일을 쓰려고 하면 예외가 발생해 곧바로 프로그램이 종료된다.
  • 따라서 예외 처리를 하여 프로그램이 비정상적으로 종료되지 않도록 한다.
[ 코드 - 동기 처리하는 메서드의 예외 처리 ]
//모듈을 추출한다.
var fs = require('fs');

//파일을 읽는다.
try {
var data = fs.readFileSync('textfile.txt', 'utf8');
console.log(data);
} catch (e) {
console.log(e);
}

//파일을 쓴다.
try {
fs.writeFileSync('textfile.txt', 'Hello World .. !', 'utf8');
console.log('FILE WRITE COMPLETE');
} catch (e) {
console.log(e);
}


[ 실행 - 동기 처리하는 메서드의 예외 처리 ]


[ 코드 - 비동기 처리하는 메서드의 예외 처리 ]

//모듈을 추출한다.

var fs = require('fs');


//파일을 읽는다.

fs.readFile('textfile.txt', 'utf8', function (error, data) {

if (error) {

console.log(error);

} else {

console.log(data);

}

});


//파일을 쓴다.

fs.writeFile('textfile.txt', 'Hello World .. !', 'utf8', function (error) {

if (error) {

console.log(error);

} else {

console.log('FILE WRITE COMPLETE');

}

});


[ 실행 - 비동기 처리하는 메서드의 예외 처리 ]




'Programming > Node.js' 카테고리의 다른 글

Node.js http 모듈  (0) 2014.11.05
Node.js 이벤트  (0) 2014.07.06
Node.js 기본 내장 모듈  (2) 2014.06.29
Node.js 전역 객체  (0) 2014.06.25
맥에서 Node.js 설치하기  (0) 2014.06.23
Node.js 개요  (0) 2014.06.14