D+7

  1. 쿠키 개념 다시 잡기

  2. 쿠키 생성/사용/불러오기 - 정확하게 이해하기

  3. JS, node.js코드 차이?

  4. 쿠키 삭제 공부 - 코드에 적용

  5. i18n 연동 예시 찾아보기


  1. 쿠키 개념 다시 잡기

    1. 쿠키에 저장되는 정보(쿠키의 속성)
      1. name : 쿠키의 이름

      2. value : 쿠키에 저장된 값

      3. masAge : 현재시간으로부터 만료 시간을 밀리초 단위로 설정

      4. expires : 쿠키가 언제 삭제되는지 결정, 만료날짜를 GMT시간으로 설정

ex) expires=”wdy, DD-Mon-YYYY HH:MM:SS GMT”

  • 쿠키에 만료일이 포함되어 있으면 영구적 쿠키로 간주

  • maxAge를 통해 지정된 만료일이 되면 쿠키가 제거됨

      1. domain : 쿠키가 사용되는 도메인을 지정

ex) domain=neso.github.io

  • 이 값이 현재 탐색중인 도메인과 일치하지 않을 경우, ‘타사 쿠키’로 간주되며 브라우저에서 거부

  • 한 도메인에서 다른 도메인에 대한 쿠키를 사용하지 못하도록 설정

      1. path : 쿠키를 반환할 경로를 결정, 디폴트 값은 ‘/’

ex) path=/

  • 도메인의 루트 경로로 이동할 경우 쿠키가 전송됨

      1. secure : 보안 연결 설정

      2. HttpOnly : 웹 서버를 통해서만 쿠키에 접근할 수 있도록 설정

      3. signed : 쿠키가 서명되어야 할 지를 결정

    1. 헤더란?
  • 요청에 대한 정보를 담고 있다. 예를들어 post방식으로 보낼 것인지 get 방식으로 보낼 것인지에 대한 정보들이 담겨있다. 여기서 get 방식은 URL 뒤에 헤더에, post방식은 body에 데이터를 넣어서 전송

  • URL뒤에 “?”마크를 통해 헤더의 시작점을 알린다.

  • key=value의 형식으로 표현된다.

ex) id=cmk&pw=1234일 때, key는 id와 pw이며 value는 cmk와 1234이다.

    1. 쿠키가 어디에 어떻게 사용되는가 (동작 방식)


      1. 쿠키는 서버에서 생성된다. 브라우저가 특정 페이지를 서버에게 요청하면 그 때 서버에서 생성한다.

      2. 응답 메시지를 헤더에 쿠키를 넣어 브라우저로 전송을 하면 브라우저는 쿠키를 모두 저장한다.

      3. 이후 브라우저는 모든 요청때마다 자신이 가지고 있는 모든 쿠키들을 http요청 메시지에 추가하여 서버로 전송한다.

      4. 이후 서버는 받은 쿠키들로 정보를 얻어 여러가지 처리를 하게 된다.


  1. 쿠키 생성/사용/불러오기

아래 코드는 name = message, value = hello가 된다.

1

Cookie cookie = new Cookie("message", "hello");





<자바스크립트>

함수를 이용한 쿠키 설정

1

2

3

4

5

6

7

8

var setCookie = function(name, value, exp) {

 var date = new Date();

 date.setTime(date.getTime() + exp*24*60*60*1000);

 document.cookie = namae + '=' + value + ';expires=' + date.toUTCString() + ';path=/';

};

setCookie('name', 'cmk', 7); // name=cmk, 7일 뒤 만료된다는 의미

setCookie('favorite', 'Blue', 7); // favorite=Blue, -1을 해주면 쿠키 삭제의 의미를 가짐



쿠키 얻기

1

2

3

4

5

6

var getCookie = function(name) {

 var value = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');

 return value? value[2] : null;

};

getCookie('name'); // 결과: cmk



쿠키 삭제

1

2

3

4

5

var deleteCookie = function(name) {

 document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';

}

deleteCookie('name');



  1. node.js에서의 쿠키생성 방법/사용 차이

req.cookies오브젝트에서 브라우저에 저장된 쿠키 값을 불러올 수 있으며, res.cookies() 메소드를 통해 쿠키값을 저장할 수 있다.

1

2

3

4

5

var express = require('express');

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

var app = express();

app.use(cookieParser());



쿠키 생성하기

{options}에는 쿠키의 속성값을 설정해주면 된다.

1

2

3

4

app.get('/login', function(req,res){

   res.cookie(key, value, {options});

   res.redirect('/');

});



쿠키 읽기

1

2

3

app.get('/current', function(req,res) {

   res.send('cookie : ' + req.cookies.key);

});



쿠키 업데이트

1

2

3

app.get('/current’, function(req,res) {

   res.cookie(key, newVal);

});



쿠키 삭제

1

2

3

app.get('/logout', function(req,res) {

   res.clearCookie(key, {path:'/process'});

});



'동계현장실습' 카테고리의 다른 글

19.01.22 화요일  (0) 2019.01.22
19.01.17 목요일  (1) 2019.01.18
19.01.14 월요일  (0) 2019.01.14
19.01.11 금요일  (0) 2019.01.11
19.01.10 목요일  (0) 2019.01.10


ㅋㅋㅋㅌㅋㅌ갸많이 틀림,,,^^ 캬ㅑ캌캬

오래전에 풀었던거라 기억은 잘 안 나즤만서도~

복습 차원에서 한 번 끄적여 봅니다



<기본적인(?) 개념>

1. '(' 일때에는 push를, ')' 일때에는 pop를 한다.

2. 스택이 비어있을 때 pop을 하게 되면 NO를 출력한다.

3. 스택이 비어있지 않았을 때 문자열에 저장된 괄호 확인(?)이 끝나면 NO를 출력한다.

4. 스택이 비어있고, 문자열에 저장된 괄호 확인이 끝나면  YES를 출력한다.


코드 설명은 주석으로 달아 놓았습니당~!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10000
 
typedef struct {
    int    max;     //스택 배열의 최대 크기
    char *stk;     //스택 표현할 배열
    int ptr;     //현재 위치
}Stack;
 
int initialize(Stack* s, int max) {
    s->ptr = 0;
    if ((s->stk = (char*)calloc(max, sizeof(char))) == NULL) {
        s->max = 0;
        return -1;
    }
    s->max = max;
    return 0;
}
 
int push(Stack* s, char x) {
    if (s->ptr >= s->max) //스택이 가득 차 있을 때
        return -1;
    s->stk[s->ptr++= x;
    return 0;
}
 
int pop(Stack* s, char *x) {
    if (s->ptr <= 0//스택이 비어있을 때
        return -1;
    *= s->stk[--s->ptr];
    return *x;
}
 
int empty(Stack* s) { //스택이 비어있으면 1, 아니면 0
    if (s->ptr <= 0//스택이 비어있을 때
        return 1;
    return 0;
}
 
int main(void) {
    Stack s;
    int num = 0, str;
    char ans2[50]= " ";
    //가장 먼저 숫자를 입력 받는다.
    scanf("%d"&num);
 
    //입력받은 숫자(num)만큼 반복
    while (num > 0) {
        //스택 초기화
        initialize(&s, MAX);
        //괄호 문자열을 입력받고 str에 문자열의 길이를 저장한다.
        scanf("%s", ans2);
        str = strlen(ans2);
        
        //입력받은 괄호 문자열을 처음부터 문자열 길이만큼 반복한다.
        for (int i = 0; i < str; i++) {
            //'('일 때, 스택에 push한다.
            if (ans2[i] == '(') {
                push(&s, ans2[i]);
            }
            //')'일 때, 스택이 비어있으면 NO를 출력
            else if (ans2[i] == ')') {
                if (empty(&s) == 1) {
                    printf("NO\n");
                    break;
                }
                //비어있지 않으면 pop한다.
                else
                    pop(&s, &ans2[i]);
            }
            
            //만약 문자열의 마지막 문자일 때,
            if (i == str - 1) {
                //비어있으면 YES를 출력, 비어있지 않으면 NO를 출력한다.
                if (empty(&s) == 1)
                    printf("YES\n");
                else
                    printf("NO\n");
            }
        }
        num--;
    }
    return 0;
}
cs



ㅜㅡㅠㅜㅡㅜㅠ휴ㅜㅠㅜ

D + 6

1. cookie-parser모듈 공부

2. 코드해결 > redirect 또는 reload 메소드 사용

3. i18n모듈 구조(?) 이해 ( json&ejs )


1. cookie & cookie-parser모듈

HTTP프로토콜은 connectionless(클라이언트가 서버에 요청을 하고 서버가 클라이언트에 응답을 보내면 접속을 끊음)이고, stateless(통신이 끝나면 상태정보를 유지하지 않음)하다. 그렇기 때문에 서버가 클라이언트를 식별할 방법이 필요하다. 그래서 쿠키와 세션을 사용한다.

쿠키는 클라이언트의 웹 브라우저에 저장되는 정보이다. 쿠키에는 이름, 값, 만료 날짜, 경로 정보가 들어있다. 쿠키는 로그인 상태를 유지하거나 사용자 정보를 일정 시간동안 유지해야 하는 경우에 주로 사용한다. 세션은 웹 서버에 저장되는 정보이다.

cookie-parser란 요청된 쿠키를 쉽게 추출할 수 있도록 해주는 미들웨어이다.

> 이와 같이 모듈 설치가 필요하다.

1

2

3

4

5

6

7

8

9

10

11

var express      = require('express')

var cookieParser = require('cookie-parser')

var app = express()

app.use(cookieParser())

app.get('/', function(req, res) {

 console.log('Cookies: ', req.cookies);

})

app.listen(3000)

cs

> req객체에 쿠키 속성이 부여된다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

var http = require('http');

// HTTP 서버 생성

http.createServer(function(request, response){

   // Request 헤더에 쿠키 정보가 있으면 쿠키 정보와 요청 헤더 출력

   if (request.headers.cookie){

       var cookie = request.headers.cookie.split(';').map(function(element){

           var element = element.split('=');

           return {

               key: element[0],

               value: element[1]

           };

       });

       // Request 헤더의 쿠키 정보만 출력

       var content = '<h1>Cookies</h1>';

       content += '<h2>'+JSON.stringify(cookie)+'</h2>';

       // Request 헤더 전체

       content += '<h1>Request headers</h1>';

       content += '<h2>'+JSON.stringify(request.headers)+'</h2>';

       response.end(content);

   // Request 헤더에 쿠키 정보가 없으면 쿠키 생성

   } else {

       // Response header의 Set-Cookie 속성을 사용하여 쿠키 생성

       response.writeHead(200, {

           'Content-Type': 'text/html',

           'Set-Cookie': ['id=cmk', 'pw=cookie']

       });

       response.end('<h1>Set cookie</h1>');

   }

// 서버 실행 (http://127.0.0.1:3000)

}).listen(3000, function(){

   console.log('Server Running at port number 3000');

});


> 쿠키를 개체에 저장하면 자동적으로 JSON으로 변환된다.


<쿠키 정보 지우기>

1. 쿠키 삭제 방법 1

1

2

3

app.get('/logout', function(req,res) {

   res.clearCookie(key);

});

cs


2. 쿠키 삭제 방법 2

1

res.request.setCookie('쿠키명', '쿠키 설정값', '시간');

cs

>쿠키 생성코드인데 ‘시간’에 -1을 주면 삭제가 된다.

2. cookieParser를 이용한 쿠키 삭제방법

1

2

3

app.get('/', function(req, res){

   res.clearCookie('lang').send(req.cookies.name);

});

cs



ㅡ> 둘의 차이를 잘 모르겠음


2. 코드 오류의 원인 찾기

1) 버튼을 눌렀을 때 바로 페이지 로딩이 되지 않는 현상인건지 확인하기 위해 reload와 redirect메소드를 사용하여 확인해 보았다. 두 메소드를 이용해서 실행해 보았지만 같은 결과가 나온다(버튼을 두 번씩 눌러야만 글자가 바뀌는 현상). 그렇기 때문에 버튼을 눌렀을 때 페이지가 로딩이 되지 않는 것은 아닌 것 같다.

2) 계속해서 관찰(?)해 본 결과 노드를 실행시키자 마자 제일 처음에 (한국어)버튼을 눌렀을 때 바로 한국어로 바뀔 때가 있고, 영어로 바뀔 때가 있었다. i18n.js파일에서 디폴트 값을 ‘en’으로 준 것 때문인지 확인해 보았으나 그것과는 상관이 없었다.

3) 이를 통해 로딩은 되지만 이전에 쿠키에 저장된 정보 때문인 것을 확인했다. 이전에 en을 저장되어 있으면 어떤 버튼을 누르든 영어로, 이전에 ko가 저장되어 있으면 한국어로 바뀌는 것이였다.

4) 그러므로 해결책은 이전에 저장된 쿠키를 초기화 시켜주어야 한다고 생각했다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

<redirect & reload>

- redirect : 특정 페이지로 강제로 보내고자 할 때 사용한다. res.redirect(‘URL’);

- reload : 소스를 수정했을 때 자동으로 서버를 재시작해줄 때 사용한다.

* 자동으로 서버를 리로드 하는 방법 : nodemon모듈을 사용한다.


<라우팅에 대한 이해가 부족함>


라우팅은 URI의 정의, 그리고 URI가 클라이언트 요청에 응답하는 방식을 말한다. 라우트 메소드는 HTTP메소드 중 하나로부터 파생된다. 라우트 경로는 요청 메소드와의 조합을 통해, 요청이 이루어질 수 있는 엔드포인트를 정의한다. 라우트 경로는 문자열, 또는 정규식일 수 있다.

* app은 express서버 객체이다.

* send는 user에 응답 데이터를 전송한다. 문자열로 응답한다.

* render은 뷰 엔진을 사용해 문서를 만든 후 전송한다.

* route()메소드는 요청패스를 지정할 수 있다.

1

2

3

4

5

6

var express = require('express');

var app = express();

app.use('/',function(req,res){

   res.send('Hello world');

});

cs

> 기본적인 라우트의 예시

1

2

3

4

app.all('/secret',function(req,res){

   console.log('ABC');

   next();

});r


> 모든 요청 메소드에 대해 한 경로에서 미들웨어 함수 로드하는데 사용

1

2

3

app.get('/about',function(req,res){

   res.send('about');

});


> 위 라우트 경로는 /about에 일치 시킨다.

> /about 대신에 정규표현식이 올 수도 있다.


ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


<<1월 15일 화요일 계획>>

  1. 아직 코드 오류에 대한 원인만 찾은 상태 ㅡ> 꼭 해결하기 (쿠키 사용해서)

  2. 쿠키 삭제방법 정확히 이해하기

  3. i18n연동 예시 찾아보기(동적인 웹페이지 만들기)



오늘 하루종일 몽롱해서 뭔가 제대로 한 게 없뜸,,,ㅎㅎ 월료일 싫어~^^


'동계현장실습' 카테고리의 다른 글

19.01.17 목요일  (1) 2019.01.18
19.01.15 화요일  (0) 2019.01.15
19.01.11 금요일  (0) 2019.01.11
19.01.10 목요일  (0) 2019.01.10
19.01.09 수요일  (0) 2019.01.09

D+5


힘듦ㅇ,,,ㅎ


1. set, get, use함수 정확히 이해

2. render메소드 이용해서 js파일 통해서 ejs파일로 넘기기

3. Node.JS와 i18n 연동(예제 코드 완벽히 이해)

4. cookie-parser 모듈 공부



1. get, set, use 사용 이해

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

var express = require('express');

var http = require('http');

var app = express();

//get메소드는 미들웨어 함수가 적용되는 HTTP메소드이다.

//'/'는 미들웨어 함수가 적용되는 경로(라우트)를 말한다.

//req:클라이언트 요청 정보를 담은 객체

//res:요청한 클라이언트로 응답을 위한

app.get('/', function(req,res,next){

   next();

});

//URL에 따라 라우팅 모듈을 설정한다

app.use('/', routes);

app.use('/users',users);

//views, 템플릿이 있는 디렉토리

app.set('views', './views');

//view engine, 사용할 템플릿 엔진

app.set('view engine', 'ejs');

cs


2. render() 메소드 이용해서 ejs파일-js파일 연결

- 아이디와 비밀번호를 입력받아서 post방식으로 넘기면(요청) 아이디와 비밀번호를 js파일의 라우터 함수를 통해 변수에 저장하여 렌더링한 후 ejs <% %>통해 변수를 적용시킨 후 ejs파일을 html코드로 화면에 띄워준다.

<성공>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

var express = require('express')

 , http = require('http')

 , path = require('path')

 , fs = require('fs')

 , ejs = require('ejs');

var LS = fs.readFileSync('./views/login_success.ejs', 'utf8');

var bodyParser = require('body-parser')

 , static = require('serve-static');

var app = express();

app.set('port', process.env.PORT || 3000);

// body-parser를 이용해 application/x-www-form-urlencoded 파싱

app.use(bodyParser.urlencoded({ extended: false }))

app.use('/public', static(path.join(__dirname, 'public')));

var router = express.Router();

router.route('/process/login').post(function(req, res) {

   console.log('/process/login 처리함.');

   

   var paramId = req.body.id || req.query.id;

   var paramPassword = req.body.password || req.query.password;

   

   var LS2 = ejs.render(LS, {userid:paramId, userpass:paramPassword});

   

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

   res.write(LS2);

   res.end();

});

app.use('/', router);

http.createServer(app).listen(app.get('port'), function(){

 console.log('Express server listening on port ' + app.get('port'));

});


<app.js 파일>


1

2

3

4

5

6

7

8

9

10

11

12

<html>

   <head>

       <meta charset = "UTF-8">

       <title>로그인 성공 페이지~!!</title>

   </head>

   <body>

       <h1>☆로그인 성공★</h1>

       <div><p>사용자 아이디 : <%= userid%></p></div>

       <div><p>사용자 비밀번호 : <%= userpass%></p></div>

   <br><br><a href='/public/login.html'>다시 로그인하기</a>

       </body>

</html>

cs

<login_success.ejs 파일>


3. Node.JS와 i18n 연동

i18n모듈을 사용하기 위해서는 npm i -S i18n을 통해 모듈 설치를 해주어야 한다.


* 실습 *

- (html파일) 본문의 글을 <한국어>버튼을 누르면 한글로, <영어>버튼을 누르면 영어로 바뀌게 하는 화면을 만들어 본다.

  1. html파일로 실행시킨다.

  2. 제출 버튼(한국어 또는 영어 버튼)을 누르면 /ko 또는 /en로 전송(요청)이 된다.

  3. app.js 파일의 라우터 함수(/ko로 요청 받았을 때, /en으로 요청 받았을 때로 나뉜다)에서 ejs파일로 렌더링 해준다.

  4. 3번의 내용은 cookie로 구분(?)해준다.

  5. ejs파일이 화면에 노출된다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

//ko로 받았을 때

router.route('/ko').get( function(req, res) {

   console.log('/ko 처리함.');

   res.cookie('lang','ko');

   res.render('index.ejs');

});

app.use('/', router);

//en으로 받았을 때

router.route('/en').get(function(req, res) {

   console.log('/en 처리함.');

   res.cookie('lang','en');

   res.render('index.ejs');

});

app.use('/', router);

cs

- app.js에서의 라우터 함수

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<html>

<head>

 <title>연습해보기</title>

</head>

<body>

   <h1 name="in"><%= __('안녕')%></h1>

   <form method="get" action="/ko">

       <input type="submit" value="한국어"/>

   </form>

   <form method="get" action="/en">

       <input type="submit" value="영어"/>

   </form>

</body>

</html>


- ejs 파일

주소도 올바르게 바뀌고 로그도 제대로 찍히지만 버튼을 두 번 눌러야 바뀐다. js파일의 라우터 내부에 문제가 있는 것 같다. reload함수나 redirect함수를 추가하면 해결할 수 있을 것 같다.

4. cookie-parser 모듈

쿠키는 클라이언트 웹 브라우저에 저장되는 정보이다. 쿠키를 사용해서 클라이언트와 서버간에 정보를 주고 받을 수 있다.

<쿠키 파서 모듈 사용 코드>

1

2

3

4

5

6

7

8

9

var express      = require('express')

var cookieParser = require('cookie-parser')

var app = express()

app.use(cookieParser())

app.get('/', function(req, res) {

 console.log('Cookies: ', req.cookies);

})



ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


1. cookie-parser모듈 공부

2. 코드해결 > redirect 또는 reload 메소드 사용

3. json&ejs



'동계현장실습' 카테고리의 다른 글

19.01.15 화요일  (0) 2019.01.15
19.01.14 월요일  (0) 2019.01.14
19.01.10 목요일  (0) 2019.01.10
19.01.09 수요일  (0) 2019.01.09
19.01.08 화요일  (0) 2019.01.08

D+4


1. 어제 공부한 내용 정리

2. 라우팅 다시 공부하기

3. 뷰 템플릿(ejs)


*do it! node.js책으로 공부한 내용입니다.


parse는 문자열을 받아 객체로 반환하고 format은 객체를 받아 문자열로 반환한다.

1

2

3

4

5

6

7

8

var url = require('url');

//주소문자열을 객체로 만들기

var curURL =

url.parse('https://www.search.naver.com/search.naver?query=steve+jobs&where=m&sm=mtp_hty');

//url객체를 문자열로 만들기

var curStr = url.format(curURL);



<일반적으로 지정하는 디렉토리 이름 정리>

  • ./node_module : express 앱에 필요한 module을 저장

  • ./public : 정적(html, css, js, 이미지 파일 등)인 파일들을 저장

  • ./views : HTML view템플릿(ejs파일)을 저장

  • app.js : 메인 소스 코드

  • package.json : module 파일로, 의존성 및 npm 스크립트 명령어를 저장


* 요청에 대한 응답을 처리하는 함수 = 미들웨어

* 각각의 요청에 맞는 함수들을 분리해주는 장치 = 라우터

* 일일이 요청 url을 일일이 확인하는 것이 번거로워, 이를 해결하는 것 = 라우터 미들웨어

1

2

3

4

5

6

7

8

9

10

11

12

// Express 기본 모듈 불러오기

var express = require('express')

 , http = require('http')

 , path = require('path');

// 익스프레스 객체 생성

var app = express();

// 기본 속성 설정

app.set('port', process.env.PORT || 3000);


app.use('/public', static(path.join(__dirname, 'public')));

cs

- 10번째 줄 코드의 설명 : 이 코드를이용해서 node.js의 포트를 설정한다. 디폴트 값을 3000으로 설정했고, 환경변수에 PORT라는 이름으로 포트명을 지정했을 경우에 그 포트명을 사용하도록 한다는 의미이다.

- 12번째 줄 코드의 설명 : 파일의 위치를 path.join(__dirname, ‘view’)로 정의하였다. __dirname은 현재 수행중인 파일의 위치를 가리킨다. 이 코드를 추가해 주고 URL을 (기존 주소/public/파일명.html)로 해 주면 된다.


1. 라우터 미들웨어 사용해서 로그인 페이지 만들기

1

<form method="post" action="/process/login">

cs

- login.html, 로그인 화면에서 post방식으로 넘겨준다. action은 url자리인데, 위와 같은 방식으로 써주면 폼 페이지를 호스팅하는 같은 서버로 전송되지만 서버의 다른 url로 전송이 된다. (기존 주소/process/login으로 전송 된다.)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

// 라우터 객체 참조

var router = express.Router();

// 라우팅 함수 등록

router.route('/process/login').post(function(req, res) {

   console.log('/process/login 처리함.');

   var paramId = req.body.id || req.query.id;

   var paramPassword = req.body.password || req.query.password;

   

   res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});

   res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>');

   res.write('<div><p>Param id : ' + paramId + '</p></div>');

   res.write('<div><p>Param password : ' + paramPassword + '</p></div>');

   res.write("<br><br><a href='/public/login.html'>로그인 페이지로 돌아가기</a>");

   res.end();

});

// 라우터 객체를 app 객체에 등록

app.use('/', router);


- app.js, html파일의 form태그에서 /process/login으로 넘겨주었기 때문에 5번째 줄의 route 함수에 ‘/process/login’을 넘겨 받으면(이전 주소/process/login이 실행 되면) 콜백 함수를 실행시켜 준다.


2. URL 파라미터 + 오류 페이지 보내기(express-error-handler 미들웨어)

url뒤에 ?기호를 붙이면 요청 파라미터(query string)을 추가하여 보낸다. URL 파라미터는 요청 파라미터와 달리 URL주소의 일부로 들어간다.

* 토큰이란?,,,


1

2

3

4

// 등록되지 않은 패스에 대해 페이지 오류 응답

app.all('*', function(req, res) {

   res.status(404).send('<h1>ERROR - 페이지를 찾을 수 없습니다.</h1>');

});


- 오류 페이지 보여주기 : 라우터 미들웨어는 특정 패스가 등록되어 있는지 순서대로 확인한다. 그렇기 때문에 post()메소드 아래쪽에 app.all()메소드를 호출해야 한다.


1

<form method="post" action="/process/login/mink">


- action값으로 ‘/process/login/mink’값을 넣었기 때문에 URL파라미터로 mink가 전달이 될 것이다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

var errorHandler = require('errorhandler');

// 에러 핸들러 모듈 사용

var expressErrorHandler = require('express-error-handler');

// 라우팅 함수 등록

router.route('/process/login/:name').post(function(req, res) {

   console.log('/process/login/:name 처리함.');

   

   var paramName = req.params.name;

   

   var paramId = req.body.id || req.query.id;

   var paramPassword = req.body.password || req.query.password;

   

   res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});

   res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>');

   res.write('<div><p>Param name : ' + paramName + '</p></div>');

   res.write('<div><p>Param id : ' + paramId + '</p></div>');

   res.write('<div><p>Param password : ' + paramPassword + '</p></div>');

   res.write("<br><br><a href='/public/login.html'>로그인 페이지로 돌아가기</a>");

   res.end();

});

// 라우터 객체를 app 객체에 등록

app.use('/', router);

// 404 에러 페이지 처리

var errorHandler = expressErrorHandler({

   static: {

     '404': './public/404.html'

   }

});

app.use( expressErrorHandler.httpError(404) );

app.use( errorHandler );


- ‘/process/login’을 ‘/process/login/:name’으로 바꾸어 주었는데, 이는 /process/login뒤에 오는 값을 파라미터로 처리하겠다는 의미이다.

- express-error-handler 미들웨어를 사용해서 404.html페이지를 응답으로 보내준다.


3. 쿠키와 세션 관리하기

사용자가 로그인한 상태인지 아닌지 확인할 때 쿠키나 세션을 사용한다. 쿠키는 클라이언트 웹 브라우저에 저장되는 정보이며, 세션은 웹 서버에 저장되는 정보이다.

cookie-parser 미들웨어 사용하여 쿠키를 설정하거나 확인한다.


4. ejs 뷰 템플릿 사용하기

MVC 패턴이란 Model-View-Controller 패턴으로 눈에 보이는 부분은 뷰, 뷰로 표현되는 데이터를 제공하는 것은 모델, 처리되는 과정을 담당하는 것은 컨트롤러로 구분한다. 다시 말해 라우팅 함수는 컨트롤러, 데이터를 저장하거나 조회하는 함수를 모델, 결과를 보여주기 위해 만든 함수를 뷰라고 한다.

express에서는 ejs, pug등의 뷰엔진을 제공한다. ejs를 사용하면 웹 문서에서 사용하는 태그를 그대로 템플릿 안에 넣을 수 있다.

1

2

app.set('views', __dirname + '/views');

app.set('view engine', 'ejs');

cs

- 뷰 엔진(속성 값)을 ejs로 설정하는 코드이다.

* ejs파일 속의 <% %>사이에는 자바스크립트 코드를 넣을수 있으며 <%= %>는 =뒤에 변수를 넣을 수 있고, 그 변수의 값을 웹 문서에 출력할 수 있다.



* 혼자 해보기 *

로그인 화면(html)에서 아이디와 패스워드를 입력 받아서 post방식으로 넘기면 이 두 파라미터를 app.js에서 userid와 userpass 변수로 렌더링을 한 후 로그인을 했다는 ejs 페이지를 띄우는 웹 페이지를 만들어 본다.

① login.html - 로그인 화면에서 아이디와 비번 입력 받고 /process/login으로 제출

② app.js - 라우터 사용해서 /process/login요청 받으면 받아온 아이디와 비번을 변수로 랜더링

③ app.js&login_success.ejs - 랜더링 한 변수를 <%= %>에 대입

④ app.js - ejs파일을 화면에 보여줌


> 랜더링 하는 부분이 잘못된 것 같다. 내일 다시 할 것

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

1. ejs 파일로 넘기는 거 다시 해 보기

2. ejs 보충 해서 공부

3. Node.JS와 i18n 연동(예제 코드 완벽히 이해)


'동계현장실습' 카테고리의 다른 글

19.01.14 월요일  (0) 2019.01.14
19.01.11 금요일  (0) 2019.01.11
19.01.09 수요일  (0) 2019.01.09
19.01.08 화요일  (0) 2019.01.08
19.01.07 월요일  (0) 2019.01.07

D+3

주요/자주 사용하는 메소드들의 이해가 부족하다. 코드를 통해 메소드 사용법 공부하고, 미들웨어와 라우팅까지 공부했당



1. 동기식IO & 비동기식IO

동기식 IO는 파일 작업이 끝날 때 까지 대기하며 비동기식 IO는 파일 작업을 요청만 하고 그 다음 작업을 바로 수행한다. 이후 파일 작업이 끝나면 그 상태는 이벤트로 받아서 처리한다.


1
2
3
4
5
6
7
var fs = require('fs');
 
var data = fs.readFile('./views/index.ejs','utf8',function(err,data){
    console.log(data);
});
 
console.log('프로젝트 안의 파일을 읽도록 요청했습니다.');
cs


비동기식 IO로 파일을 읽어들이는 방식이다. 파일을 읽기 전에 먼저 console.log가 먼저 실행된다. 에러를 확인할 수 있기 때문에 비동기식 방식을 더 많이 사용한다.

* require(‘readline’) 모듈은 line-by-line으로 읽어오도록 한다. 이 모듈을 호출하면 인터페이스와 STDIN스트림을 닫을 때 까지 프로그램이 종료되지 않기 때문에 readline.createInterface(instream, process.stdout);와 함께 사용한다.

* on(event, listener) 메소드 : 지정한 이벤트의 리스너를 추가한다. on(‘exit’, function())는 exit를 발생시킨다는 의미이다.


2. buffer 사용법

(1)

var buf1 = new Buffer(10); //크기를 먼저 할당한 후

buf1.write(‘안녕’, ‘utf8’); //문자열을 입력하는 방식

(2)

var buf2 = new Buffer(‘안녕’, ‘utf8’); //buffer를 만듦과 동시에 문자열을 입력하는 방식

* isBuffer()메소드 : 변수에 들어있는 것이 벼퍼인지 아닌지 확인할 때 사용한다.


3. 스트림 단위로 파일 읽고 쓰기

스트림이란 데이터가 전달되는 통로를 말한다.

- createReadStream(path, [options]) : 파일을 읽기 위한 스트림 객체를 만든다.

- createWriteStream(path, [options]) : 파일을 쓰기 위한 스트림 객체를 만든다.

1
2
3
4
5
6
var fs = require('fs');
 
var infile = fs.createReadStream('./output.txt', {flags: 'r'});
var outfile = fs.createWriteStream('./output2.txt', {flags: 'w'});
 
infile.pipe(outfile);
cs


스트림 객체를 각각 생성해 준 후 pipe() 메소드로 연결해 주면 output.txt의 파일의 내용을 읽어와서 output2.txt 파일에 작성한다.


4. 로그 파일

console객체의 log()나 error() 메소드를 통해 로그를 출력할 수 있으나, 프로그램의 크기가 커지면 로그의 양도 많아지기 때문에 로그를 보관하는 방식이 중요하다. 그래서 외부 모듈을 사용한다.

로그 레벨이란? 어떤 정보(오류수준)까지 출력하여 알려줄 것인지 결정하는 것을 말한다.

debug:0 > info:1 > notice:2 > warning:3 > error:4 > crit:5 > alert:6 > emerg:7


5. 웹 서버 만들기

http.createServer() : 웹 서버 객체를 만드는 것

listen() 메소드 : 웹 서버 시작하는 메소드

connection 이벤트 :  클라이언트가 접속하여 연결이 만들어질 때 발생하는 이벤트

request 이벤트 : 클라이언트가 요청할 때 발생하는 이벤트

Content-Type은 데이터 타입을 말하는 것인데, Content-Type에는 text/plain, text/html, text/css, image/jpeg, image/png, video/mpeg, audio/mp3등이 있다.

1
2
3
4
5
6
7
8
server.on('request',function(req,res){
    console.log('클라이언트 요청이 들어왔습니다.');
   var filename = '4.png';
   fs.readFile(filename, function(err,data){
       res.writeHead(200, {"Content-Type":"image/png"});
       res.write(data);
       res.end();
   });
cs

클라이언트의 요청에 의해 png 파일을 불러올 때의 코드이다.

writeHead메서드는 스트림에 상태코드와 헤더를 작성한다. 일단 헤더를 설정하고 나면 응답 데이터를 전송할 준비가 된 것이다.

1
2
3
4
5
6
7
server.on('request',function(req,res){
    console.log('클라이언트 요청이 들어왔습니다.');
       var filename = '4.png';
       var infile = fs.createReadStream(filename, {flags:'r'});
    
    infile.pipe(res);
  });
cs

write메소드에서 Content-Type지정 필요없이 pipe()메소드를 사용하면 다른 설정 필요없이 알아서 처리가 된다. 하지만 이방법으로는 헤더를 설정할 수 없는 등의 제약이 생길 수 있다.


6. Express로 웹 서버 만들기&미들웨어 사용해 보기

* 미리 만들어 둔 여러가지 미들웨어들이 있지만 기본 개념만 공부

1
2
3
//express의 기본 모듈 불러오기
var express = require('express');
var http = require('http');
cs

> express모듈은 웹 서버를 위해 만들어진 것으로 http모듈 위에서 동작한다. 따라서 둘은 항상 같이 붙어다닌다.

<자주 사용하는 메소드들>

set(name, value) 메소드 : 서버 설정을 위한 속성을 지정한다.

get(name) 메소드 : 서버 설정을 위해 지정한 속성을 꺼내온다.

use([path], function) 메소드 : 미들웨어 함수를 사용한다.

get([path], function) 메소드 : 특정 패스로 요청된 정보 처리한다.

- 미들웨어 : 익스프레스에서는 웹 요청과 응답에 관한 정보를 사용해 필요한 처리를 진행할 수 있도록 독립된 함수로 분리한다. 이 독립된 함수들을 미들웨어라고 한다. 예를 들어서 use() 메소드를 사용해서 이전에 만들어 놓은 함수를 미들웨어로 등록해두면, 그 함수를 실행시킬때 이 미들웨어를 거치면서 함수를 실행시킨다.

* 미들웨어는 use() 메소드를 사용하여 설정 next() 메소드를 이용하여 다음 미들웨어로 넘어갈 수 있음

- 라우터 : 클라이언트의 요청패스를 보고 이 요청 정보를 처리할 수 있는 곳으로 기능을 전달해 주는 역할을 한다. 즉 클라이언트의 요청에 따라 각각을 담당하는 함수로 분리시키는 일을 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//express의 기본 모듈 불러오기
var express = require('express');
var http = require('http');
 
var app = express();
 
app.use(function(req, res, next){
    console.log('첫번째 미들웨어에서 요청을 처리한다.');
    req.user='mike';
    console.log(req.user);
    next();
});
 
app.use(function(req, res, next){
    console.log('두번째 미들웨어에서 요청을 처리한다.');
    res.writeHead('200',{'Content-Type':'text/html;charset=utf8'});
    res.end('<h1>Express server 에서' + req.user+ '응답한 결과입니다.</h1>');
});
 
//express서버 시작
http.createServer(app).listen(3000,function(){
    console.log('익스프레스 서버가 3000에서 시작됨');
});
cs

두 개의 미들웨어를 사용하여 첫 번째 미들웨어에서 다음 미들웨어로 넘어가도록 하는 코드이고 아래는 그 결과이다.


* redirect() 메소드를 사용하면 다른 페이지로 이동할 수 있다! 또한 URL주소뿐만 아니라 프로젝트 폴더 안에 있는 다른 페이지를 보여줄 수 있다.

* render() 메소드는 뷰 엔진을 사용해 템플릿 파일에 있는 내용을 HTML페이지로 바꾼 후 그 결과물을 전송한다.


<post방식으로 요청했을 때(body-parser미들웨어를 사용)>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Express 기본 모듈 불러오기
var express = require('express')
  , http = require('http')
  , path = require('path');
 
// Express의 미들웨어 불러오기
var bodyParser = require('body-parser')
  , static = require('serve-static');
 
 
 
// 익스프레스 객체 생성
var app = express();
 
// 기본 속성 설정
app.set('port', process.env.PORT || 3000);
 
// body-parser를 이용해 application/x-www-form-urlencoded 파싱
app.use(bodyParser.urlencoded({ extended: false }))
 
// body-parser를 이용해 application/json 파싱
app.use(bodyParser.json())
 
app.use('/public',static(path.join(__dirname, 'public')));
 
// 미들웨어에서 파라미터 확인
app.use(function(req, res, next) {
    console.log('첫번째 미들웨어에서 요청을 처리함.');
 
    var paramId = req.body.id || req.query.id;
    var paramPassword = req.body.password || req.query.password;
    
    res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});
    res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>');
    res.write('<div><p>Param id : ' + paramId + '</p></div>');
    res.write('<div><p>Param password : ' + paramPassword + '</p></div>');
    res.end();
});
 
 
// Express 서버 시작
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});
cs

* 혼란1 * 24번째 줄이 ‘public’폴더에 있는 html문서를 불러오는 코드이다…

* 혼란2 * static미들웨어 : 특정 폴더의 파일들을 특정 패스로 접근할 수 있도록 해 준다. 위 코드는 public폴더 안의 파일에 접근할 수 있도록 해 준다. 만약 파일 이름이 login.html이라면 <http://localhost:3000/login.html>로 접근이 가능하다!


7. 요청 라우팅하기

클라이언트로부터 로그인이 아닌 다른 요청이 들어온다면 일일이 URL을 확인해야 하는 번거로움을 없애주는 것이 라우터 미들웨어이다. 사용자가 요청한 기능이 무엇인지 패스를 기준으로 구별한다.


----------------------------------------------

Action Item

  1. Router 재공부 / Vue Template (EJS 학습)

  2. Node.JS와 i18n 연동 (~1/11일)

  3. Language Pack은 언제쯤?? -> 8주 전에는 무조건!!! 나와야함


'동계현장실습' 카테고리의 다른 글

19.01.14 월요일  (0) 2019.01.14
19.01.11 금요일  (0) 2019.01.11
19.01.10 목요일  (0) 2019.01.10
19.01.08 화요일  (0) 2019.01.08
19.01.07 월요일  (0) 2019.01.07

+ Recent posts