posted by 지니우스 2020. 1. 14. 16:28

SELECT dt + INTERVAL lv-1 DAY dt
  FROM (
            SELECT @ROWNUM:=@ROWNUM+1 AS lv
                    , CONCAT('202001','01') dt
             FROM information_schema.`COLUMNS` A
                   , (SELECT @ROWNUM:=0) R
              LIMIT 100
          ) a

posted by 지니우스 2017. 11. 16. 14:34
$ npm install hubot-test-helper --save-dev

testing hubot scripts를 읽던 중 발견. --save를 쓰기도 하던데 둘 차이는 뭘까?

그냥 install 하면 ./node_modules 디렉터리에 패키지 설치를 하고 끝. --save, --save-dev 옵션은 ./package.json 업데이트를 같이해준다. 어디에 패키지 정보를 추가하느냐가 다른데, --save 옵션은 dependencies object에 추가하고 --save-dev 옵션은 devDepenencies object에 추가한다.

dependencies와 devDepenencies 차이는 npm install을 할 때 나타난다. dependencies는 항상 설치되고 devDepenencies는 --production 옵션을 붙이면 빠진다. npm install “$package” 명령어로 설치할 때는 --dev 옵션을 붙여야지만 설치된다.

참고


출처:  http://ohyecloudy.com/ddiary/2016/09/04/til-npm-install-save-or-save-dev/


posted by 지니우스 2017. 7. 7. 14:33

오늘은 얼마 전 심심해서 열어본 jquery 소스를 보고 메모해야지 했던 call과 apply에 대한 내용을 적어봐야지... 귀찮아서 계속 미루게 된다;

발단은 이러하다. 아주 아주 예~전에 사두어서 읽다가 책장으로 쳐박아둔 javascript patterns 책을
어쩌다 다시 보게 되면서 call과 apply 및 curring 부분에서 큰 재미를 얻을 수 있었는데

마침 어쩌다 열어 본 jqeury 3.1.1 소스에서 call, apply에 대한 예시를 적기에 딱! 좋은 부분이 발견되어 메모겸 적어놔야지 생각하게 되었다.


1. javascript api function 할당? 사용? 대입?


위에 소스를 보면 머 아시는 분들이야 다 아시겠지만 주목해야 할 부분이 있다.

var arr = []; // new Array();와 동일한데 쓰지말자 이유는 생략한다 var slice = arr.slice; var concat = arr.concat; var push = arr.push; var indexOf = arr.indexOf; var class2type = {}; // new Object();와 동일 var hasOwn = class2type.hasOwnProperty; console.log('arr', arr); console.log('slice', slice); console.log('class2type ', class2type ); console.log('hasOwn ', hasOwn );
console

위에 코드를 콘솔로 날리면 대략 저런 결과가 나온다.
참고로 __proto__는 private 변수 선언 정도로 생각하면 된다.
별도 검색해 보면 내용이 많이 나올 것이다. 일단 여기선 생략

slice function () { {native code} } 보이시는 가

slice 변수에 javascript Array 객체의 slice function이 대입되었다.

이말인 즉 javascript에서 기본으로 제공하는 api들을
내 임의로 변수에 할당하여 사용할 수 있다는 말이다.
위에 slice를 예를 들면 동일한 기능을 하는데 구지 내가 function을 하나하나 만들어가면서 삽질하지 않아도 된다는 것이다.

테스트는 안해 봤지만 성능도 native code로 동작하니 더 빠르겠지 ; (솔직히 이건 좀  100% 자신은 없다만;;)

2. apply, call 활용
// 샘플코드 출처 : http://www.w3schools.com/jsref/jsref_slice_array.asp var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"]; var citrus = fruits.slice(1, 3); // Orange,Lemon


slice 사용을 예로 들어보자 사용법은 저렇다.
근데 잘보면 저건 fruits가 Array니까 저렇게 사용 가능한 것이다.

근데 var slice = Array.slice ;;; ?? 헐 어찌 사용하노 this가 뭣인지 알고

이럴 때 적절히 사용 할 수 있는 것이 call, apply다
가장 핵심은 function 실행 시 this로 사용될 값을 파라미터로 넘길 수 있다는 것이다.
음 사람들이 간혹 이걸 보고 상속라 말하기도 한다. (내 생각은 약간 다르다.)

function add(a, b) { var result = a + b; console.log('this', this) console.log('name', this.name); console.log('return', result); return result; } var me = { name : 'lks' }; add(10, 20); add.apply(me, [100, 200]); // add.call(me, 100, 200);

우선 위에 코드만 보면

add(10, 20) 의 경우 실행 시 console.log('this', this); 부분의 this는 window
반면 add.apply(me, [100, 200]); 에서는 'lks' 가 찍히는데

apply() Syntax fun.apply(thisArg[, argsArray]) Parameters fun : 위와 동일 thisArg : this 객체로 사용될 객체 argsArray : 함수에 전달할 인수 집합 인데 배열로 전달한다. call은 인수로 보내고 apply는 배열로 보낸다.
call() Syntax : fun.call(thisArg[, arg1[, arg2[, ...]]]) Parameters fun : 가져다쓸 메소드 thisArg : this 객체로 사용될 객체 arg1,arg2,arg3 : 메소드에 전달할 인자목록

위와 같은 구조이기 때문에 그렇다.
보면 첫번째 인자로 function 내의 this 넘긴다.
그렇기 때문에 add 실행 시에는 그냥 window가 찍히고
apply를 통해 me를 변수로 넘겼을 때는 me의 name = 'lks' 가 찍힌 것이다.

그럼 위 slice를 사용해 보자

var slice = [].slice; console.log( slice ); var me = [ 'A', 'B', 'C', 'D', 'E' ]; console.log('apply me 1', me); me = slice.apply( me, [1, 3] ); console.log('apply me 2', me); console.log('-------------------------------------'); me = [ 'A', 'B', 'C', 'D', 'E' ]; console.log('call me 1', me); me = slice.call( me, 1, 3 ); console.log('call me 2', me);


별거 아닌 내용인 것 같기도 한다.
일반적으로 사용하는 경우도 드물 것이다.
그러나 this를 넘길 수 있다는 건 매우 매력적인 기능이 아닌가 싶다.


posted by 지니우스 2017. 6. 27. 14:01

출처 QuirksMode | QuirksMode
원문 http://blog.naver.com/box252/220350058395

1.javascript 사용의 일반적인 구문


일반적으로 우리는 자바스크립트를 head에 선언하여 사용합니다.


<일반적인 구문>

<head>

  <script type="text/javascript" src="function.js">

</head>


하지만 HTML문서가 스크립트 파일을 만났을 때 DOM의 로딩은 정지가 된 상태로 백지화면만 보여지게 됩니다.

그래서 생각해낸 방법이 해당 DOM아래 스크립트를 위치 시키는거였습니다.


<DOM의 아래에 스크립트 위치>

<div>

  //Function.js 라이브러리를 활용한 구문

</div>

<script type="text/javascript" src="function.js">



2.defer와 async 


defer와 async속성은 스크립트 구문에 사용하며 아래 그림으로 축약 할 수 있습니다.


 


일반적인 스크립트 구문은 HTML파싱중 스크립트 구문을 만나면 전송 받고 실행을 합니다.

defer 속성을 사용시에는 파싱과 스크립트를 동시에 전송받고 파싱이 완료된 후 실행합니다.

async 속성을 사용시에는 파싱과 스크립트를 동싯에 전송받지만 실행시에는 파싱을 멈춥니다.


<defer, async>

<head>

  <script type="text/javascript" defer src="example.js">

  <script type="text/javascript" async src="example.js">

</head>


※ XHTML문서에서는 defer="defer" 형태로 사용해야 합니다.


posted by 지니우스 2017. 6. 26. 14:21

참고: https://stackoverflow.com/questions/4797050/how-to-run-process-as-background-and-never-die



1안) nohup을 사용. 출력을 /dev/null 로 내보내기.


nohup node server.js > /dev/null 2>&1 &

  1. nohup means: Do not terminate this process even when the stty is cut off.
  2. > /dev/null means: stdout goes to /dev/null (which is a dummy device that does not record any output).
  3. 2>&1 means: stderr also goes to the stdout (which is already redirected to /dev/null). You may replace &1 with a file path to keep a log of errors, e.g.: 2>/tmp/myLog
  4. & at the end means: run this command as a background task.


2안) pm2 패키지 설치해서 사용하기.


Nohup and screen offer great light solutions to running Node.js in the background. Node.js process manager (PM2) is a handy tool for deployment. Install it with npm globally on your system:

npm install pm2 -g

to run a Node.js app as a daemon:

pm2 start app.js




posted by 지니우스 2017. 5. 31. 13:18

출처: http://mainia.tistory.com/2428


1. escape(), unescape() 함수


▼ 아스키문자에 해당하지 않는 문자들은 모두 유니코드 형식으로 변환해 줍니다. 그러니까 16진수 형태로 바꿔주는 것이죠. 표기법은 1바이트일때 %XX 이며 2바이트 일때는 %uXXXX 입니다. 앞에 u 가 하나 더 붙죠. 그리고 16진수에서는 문자 2개가 하나의 바이트를 이룹니다. 


[입력]

document.write(escape("인코딩, escape"));


[출력]

%uC778%uCF54%uB529%2C%20escape



2. encodeURI() 함수


 encodeURI 는 URL 주소표시를 나타내는 앞자리 특수문자는 인코딩하지 않습니다. 인코딩 하지 않는 문자는 ": ; / = ? &" 입니다. 주소를 통해 넘기는 파라미터를 인코딩할때 사용합니다.


[입력]

document.write(escape("http://녹두장군.com")+ "<br/>");

document.write(encodeURI("http://녹두장군.com"));


[출력]

http%3A//%uB179%uB450%uC7A5%uAD70.com

http://%EB%85%B9%EB%91%90%EC%9E%A5%EA%B5%B0.com



3. encodeURLComponent() 함수


 encodeURI 와 달리 주소를 나타내는 특수문자도 인코딩을 하게 됩니다. 모든 문자를 인코딩 하기 때문에 경로를 나타내는 /file/exe/index 값이 있다면 "/" 도 인코딩하기 하게 됩니다. 이렇게 되면 서버에서는 인식을 못합니다. 이럴때는 encodeURI 를 사용해야 합니다. 다시 디코딩을 하시려면 decodeURIComponent() 함수를 사용합니다.


[입력]

document.write(encodeURI("http://mainia.tistory.com?id=홍길동&phone=010") + "<br/>");

document.write(encodeURIComponent("http://mainia.tistory.com?id=홍길동&phone=010"));


[출력]

http://mainia.tistory.com?id=%ED%99%8D%EA%B8%B8%EB%8F%99&phone=010

http%3A%2F%2Fmainia.tistory.com%3Fid%3D%ED%99%8D%EA%B8%B8%EB%8F%99%26phone%3D010



posted by 지니우스 2017. 5. 24. 12:52
출처 : http://cafe.daum.net/program-db/cFz8/20?q=node.js%20express

  • 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-addd - :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-addd - :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.cookie‎Parser()가 사용되지 않으므로 이것으로 사용한다.

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

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

//서버를 실행한다.
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.cookie‎Parser()가 사용되지 않으므로 이것으로 사용한다.


//서버를 생성한다.

var app = express();

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

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


//라우터를 설정한다.

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

    //응답한다.

    response.send(request.cookie‎s);

});

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.get('/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.cookie‎s.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(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) {
    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.cookie‎s = request.cookie‎s;

    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.cookie‎s = request.cookie‎s;
    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인 데이터에 대해 삭제를 하였다.


posted by 지니우스 2017. 5. 23. 23:30

> npm이란?

npm은 Node.js의 모듈을 관리하는 패키지 관리자다. 기본적으로 Node.js의 모듈을 설치하는 목적으로 사용된다. 그리고 Node.js로 만든 애플리케이션을 설치할 수도 있다.


> npm install 로 모듈 설치

그러면 npm의 기본적인 사용법을 알아보자. 모듈을 설치할 때에는 'npm install'을 사용한다. 커맨드 라인 창에서 다음과 같이 명령어를 입력한다.


[서식] npm으로 모듈 설치

$ npm install (모듈 이름)


예를 들면, 웹사이트로부터 파일이나 데이터를 내려받을 때에는 request 모듈을 많이 사용한다. request 모듈을 설치하기 위해서는 다음과 같이 입력하면 된다.


$ npm install request


그러면 다음과 같은 화면을 볼 수 있다.


▲ npm 실행 화면


위 화면에서 볼 수 있듯이 npm install을 실행하면 그 모듈에서 사용하는 다른 모듈(즉, 의존 모듈)도 같이 설치된다. 따라서 request 모듈을 사용하기 위해 mime-types 모듈과 form-data 모듈을 따로 설치하지 않아도 된다. 이것은 npm을 이용할 때의 커다란 장점으로 매우 편리한 기능이다.


- 모듈이 설치되는 경로

그러나 주의해야 할 점이 있다. 기본적으로 'npm install'로 모듈을 설치하면 이 명령을 실행한 현재 디렉터리에 모듈이 다운로드된다. 정확하게는 현재 디렉터리에 node_modules라는 디렉터리가 만들어지고, 그 안에 모듈이 다운로드된다.


그래서 한 번 모듈을 설치했어도 다른 디렉터리에 배치된 프로젝트에서는 그 모듈에 접근할 수 없다. 여기서 잠시 정리해 보자. 다음과 같은 디렉터리 구성으로 두 개의 프로그램이 있다고 하자.


+ <root>

|---+ <ProjectA>

|    |---+ <node_modules>

|    |--- program-a.js

|

|---+ <ProjectB>

|    |--- program-b.js 


<Project A>의 program-a.js에서 request 모듈을 사용하기 위해 Project A의 디렉터리에서 npm install request를 실행했다고 하자. 그러면 program-a.js에서는 request 모듈을 사용할 수 있게 된다. 그러나 Project B의 program-b.js에서는 request 모듈을 발견할 수 없으므로 Project B의 디렉터리에서 다시 request 모듈을 설치해야 하는 것이다.


- 글로벌 설치 -g

그러나 자주 사용되는 모듈을 매번 설치하는 것은 성가신 일이다. 모든 프로젝트 및 폴더에서 사용하고 싶다면 모듈을 설치할 때 -g 옵션을 붙인다. 그러면 글로벌한 경로에 모듈이 설치된다.


# 모듈을 글로벌하게 설치

$ npm install -g (모듈 이름)


-g 옵션을 붙여서 설치하는 것을 글로벌 설치라고 하고, 그렇지 않은 경우를 로컬 설치라고 한다. 글로벌 설치를 할 때의 주의점은 대부분의 환경에서 관리자 권한이 필요하다는 점이다. CentOS나 Mac OS X에서는 명령어 앞에 sudo를 붙여서 관리자 권한으로 명령을 실행할 수 있다.


# 관리자 권한으로 글로벌 설치

$ sudo npm install -g (모듈 이름)


sudo로 명령어를 실행하면 패스워드를 물어 보는데 이때 관리자 패스워드를 입력하도록 한다.

올바른 패스워드로 관리자 권한이 확인되면 관리자 권한으로 명령어가 실행된다.


- 글로벌 설치 시 PATH에 주의

npm을 통해 모듈을 글로벌하게 설치하면 CentOS5에서는 /usr/lib/node_modules에 설치된다. Mac OS X에 Homebrew로 설치한 경우에는 /usr/local/lib/node_modules에 설치된다. 어디에 모듈이 설치되는지는 다음 명령어로 확인할 수 있다.


# 글로벌 설치 경로 확인

$ npm root -g


그런데 npm으로 글로벌하게 설치한 모듈을 Node.js가 찾을 수 없다며 다음과 같은 에러 메시지가 표시되는 경우가 있다.


Error: Cannot find module '(모듈 이름)'


이것은 해당 모듈을 아직 설치하지 않았거나 Node.js에서 npm으로 글로벌하게 설치한 모듈을 찾을 수 없을 때 발생하는 에러 메시지다. 그렇다면 Node.js가 모듈을 찾을 때 어떤 경로를 검색할까? 다음 명령어를 통해 확인할 수 있다.


$ node -e "console.log(global.module.paths)"


CentOS에서는 다음과 같이 나타난다.


[ '/home/nodejs/node_modules',

  '/home/node_modules',

  '/node_modules' ]


잘 보면 현재 작업 디렉터리의 node_modules 폴더, 그리고 그 상위 폴더의 node_modules폴더, 다시 그 상위 폴더의 node_modules 폴더 .. 이러한 순으로 차례대로 모듈을 검색하는 것을 알 수 있다. 이와 별개로 Node.js는 환경 변수 NODE_PATH에 저장된 경로도 검색한다.


결론적으로, npm의 글로벌 모듈 설치 경로를 환경 변수 NODE_PATH에 등록하면 Node.js에서 모듈을 찾을 수 있게 된다.


다음은 가상 머신의 CentOS에서 'npm root -g'를 실행한 결과다.


$ npm root -g

/home/nodejs/.nvm/versions/node/v0.12.4/lib/node_modules


리눅스(CentOS)나 Mac OS X에서 환경 변수 값을 등록하려면 사용자의 홈 디렉터리에 있는 '~/.bash_profile'(가상 머신 환경에서는 '/home/nodejs/.bash_profile')을 편집한다. 다음과 같이 NODE_PATH에 npm의 글로벌 설치 경로를 지정한다.


# 환경 변수 NODE_PATH 설정

export NODE_PATH=/home/nodejs/.nvm/versions/node/v0.12.4/lib/node_modules



출처: 자바스크립트와  Node.js를 이용한 웹 크롤링 테크닉

posted by 지니우스 2017. 5. 23. 22:50

자바스크립트 엔진인 Node.js를 설치하자. 

Node.js는 버전에 따라 동작이 다르다. 그래서 nvm이라는 도구를 사용해서 특정 버전의 Node.js를 설치할 것이다.

먼저, 다음과 같은 명령어를 통해 nvm을 설치한다.


$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.3/install.sh | bash


설치 후 셸의 재시작을 위해 'logout' 명령어를 이용하여 로그아웃하였다가 재접속하여 다시 로그인한다. 이어 Node.js 0.12.4를 설치한다.


$ nvm install v0.12.4

$ nvm alias default v0.12.4


제대로 설치되었는지 확인해 보자. 'node -v' 명령어로 설치된 Node.js의 버전 정보를 확인할 수 있다. 다음과 비슷하게 표시되면 성공한 것이다.


$ node -v

v0.12.4


Node.js에는 REPL(Read-Eval-Print-Loop)이라 불리는 대화 환경이 준비되어 있다. 터미널에서 인자 없이 node 명령어를 실행하면 REPL이 시작된다. 여기서 3 + 5라 입력하고, 엔터를 눌러보자. 8이라는 결과가 표시될 것이다.


$ node

> 3 + 5

8


그런데 nvm을 사용해서 Node.js를 설치한 경우에는 sudo 명령어와 함께 npm이나 node 명령어를 사용할 수 있다. 이를 위해 sudo 명령을 실행할 때의 패스(PATH: 프로그램이나 명령을 찾는 기본 경로를 담고 있는 환경 변수)를 일반 사용자의 패스와 같게 해야 한다. 먼저, '.exit'를 입력하여  REPL 환경을 종료하고 다음과 같이 visudo 명령어를 실행하도록 한다.


$ sudo visudo


많은 설정 항목이 있는데 env_keep을 설정한 행을 찾아서 주석 표시 '#'을 없애도록 한다. 그런데 visudo를 실행하면 vi 에디터가 실행된다. vi 에디터는 명령 모드와 문자를 입력할 수 있는 입력 모드를 바꿔가면서 편집을 수행한다. vi를 실행하면 명령 모드로 시작된다. i 키를 눌러 입력 모드로 변환하여 편집을 수행하고, 편집이 끝나면 esc 키를 눌러 명령 모드로 돌아가도록 한다.


### 첫 번째 수정(env_reset을 무효화)

Defaults env_reset

         ↓

Defaults !env_reset


### 두 번째 수정(HOME을 추가)

#Defaults env_keep += "HOME"

         ↓

Defaults env_keep += "HOME"

### 세 번째 수정(sudo 명령어 실행 시 사용할 패스를 덮어쓰지 않도록 주석 처리한다)
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin

         ↓

#Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin


명령 모드에서 :wq 키를 누르면 저장 후 vi가 종료된다. 한 번 로그아웃하고 다시 로그인하면 설정이 반영된다.




[덤] git 설치


$ sudo yum install git



출처: 자바스크립트와  Node.js를 이용한 웹 크롤링 테크닉

posted by 지니우스 2017. 5. 22. 15:17

출처: http://blog.naver.com/aonezip/220846868749


Bash Shell도 충분히 멋지지만, Zsh를 이용하면 git를 터미널로 사용할 때 여러모로 편리하다. 또한 몇몇 기능은 나 같은 귀찮니즘이 많은 골수 윈도우 유저에게 많은 도움이 준다. 그럼으로 처음 리눅스를 설치하면, Bash에서 Zsh로 변경해서 사용하자. CentOS, Ubuntu에서 잘 작동한다.

현재 사용 Shell 확인

echo $SHELL

설치된 Shell 목록

cat /etc/shells

Zsh 설치

Ubuntu : sudo apt-get install zsh CentOS : sudo yum -y install zsh

shell 변경

Ubuntu : chsh -s /usr/bin/zsh CentOS : chsh -s /bin/zsh


터미널 접속을 끊고 다시 접속하면, Zsh로 된다. 접속하면 아래와 같은 문구가 나오는데, 0이나 혹은 2번을 선택하여 ./zshrc가 생성되도록 한후, Oh my Zsh설치하면 된다.

This is the Z Shell configuration function for new users,
zsh-newuser-install.
You are seeing this message because you have no zsh startup files
(the files .zshenv, .zprofile, .zshrc, .zlogin in the directory
~). This function can help you with a few settings that should
make your use of the shell easier.

You can:

(q) Quit and do nothing. The function will be run again next time.

(0) Exit, creating the file ~/.zshrc containing just a comment.
That will prevent this function being run again.

(1) Continue to the main menu.

(2) Populate your ~/.zshrc with the configuration recommended
by the system administrator and exit (you will need to edit
the file by hand, if so desired).


Oh my Zsh 설치

via curl sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" via wget sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"


테마 agnoster로 변경

vi ~\.zshrc ZSH_THEME="robbyrussell" 를 ZSH_THEME="agnoster" 로 변경

이후 터미널을 다시 접속하면 적용된다. 그럼 다음과 같이 Zsh가 작동하는 걸 볼 수 있다.


Note! 만약 설치가 안되면, 아래 사이트에서 변경된 점이 있나 확인하자.

zsh : http://www.zsh.org/
on my zsh gitHub : https://github.com/robbyrussell/oh-my-zsh