본문 바로가기
○ WEB/19.06 생활코딩_Node.js

3. Template Engine이란 / Jade,pug 사용법 / 쿼리객체 / Semantic Web/ POST / GET

by 0ver-grow 2019. 6. 28.
반응형

템플릿엔진이란?

템플릿 양식과 특정 데이터 모델에 따른 입력 자료를 합성하여 결과 문서를 출력하는 소프트웨어(또는 소프트웨어 컴포넌트)를 말한다.

그 중 웹 템플릿 엔진(web template engine)이란 웹 문서가 출력되는 템플릿 엔진을 말한다.

즉, 웹 템플릿 엔진은 웹 템플릿들(web templates)과 웹 컨텐츠 정보(content information)를 처리하기 위해 설계된 소프트웨어이다.

 

동적, 정적 파일을 섞은 것을 템플릿엔진이라고 한다.

템플릿 엔진을 이용하면 다음과 같이 간단하게 만들 수 있다.

오른쪽이 템플릿 엔진.

규모있는 사이트를 만들 때 템플릿 엔진을 쓰면 이점이 많다.

템플릿 엔진 'jade' 설치

Express사이트에선 Jade가 아닌 pug가 쓰여져 있으나

우선, 수업에서 말한 대로 설치를 진행하겠다.

고로

npm install jade --save 를 입력해준다.

jade 사용하기

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

는 사용할 템플릿 엔진을 express에게 알려주는 코드이다.

고로

app.js에 위 내용을 추가시킨다.

이렇게 설치한 jade템플릿 엔진과 express를 연결하는 코드가 바로 이것이다.

그리고

뎀플릿이 있는 디렉터리를 알려주는 코드는

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

이다.

이후에는

views라는 디렉터리를 만들어야 한다.

앞으로 jade파일은 이 views디렉터리에 넣어야한다.

jade express에선 template 파일의 이름은 views이다.

설령, app.set('views','./views)를 생략해도 express는 기본적으로 views디렉터리를 찾음

이제 홈페이지에 적용될 라우터를 만들어보자

기존에 데이터를 전송할 때 res.send를 사용했지만 이번에는

res.render('템플릿파일의이름');를 쓴다. jade를 쓰기 위해서임

res객체는 send뿐만아니라 render란 메서드도 가지고 있음

template라는 경로(/template)를 통해 들어온 사용자에게

function이 실행되면서

temp라는 템플릿 파일을 웹페이지로 렌더링해서 전송한다는 의미.

이 temp 템플릿 파일은

views디렉터리 안의 temp.jade라는 템플릿 jade 파일을 의미한다. (이 파일을 생성시키자)

그리고

temp.jade 안에

html 만을 입력한다.

이렇게 해준뒤

node app.js를 실행시키고

127.0.0.1:3000/template로 들어가면

아무것도 뜨지 않는다.

그러나

우클릭으로 페이지 소스보기를 클릭하면

위처럼 나온다.

 

app.set('view engine', 'jade'); // 6-1 jade템플릿 엔진과 express를 연결하는 코드

app.set('views','./views'); // 6-2.템플릿있는 디렉터리(./views) 알려줌
// jade express에선 template 파일의 이름은 views이다.
// 설령, 이 코드가 없어도 express는 기본적으로 views디렉터리를 찾음

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

// 6-3. jade 템플릿 파일 사용하기 
app.get('/template', function(req,res){
    res.render('temp'); // temp라는 템플릿 파일을 웹페이지로 렌더링해서 전송한다
    //views디렉터리 안에 temp.jade를 의미
    //우리가 6-1에서 템플릿엔진을 jade로 정의해놨기 때문에 jade의 확장자인 temp.jade를 찾아서 내부 소스를 jade문법에 맞춰 해석한 뒤 response해준다.
});

+)

수정한 뒤에는 항상 다음처럼 재입력해서 실행했어야 했다

node app.js

그런데

supervisor app.js를 입력하면 수정시 알아서 자동 재시작을 해준다.

 

jade 문법

들여쓰기 안해주면 이렇게 된다.

들여쓰기를 해줘도 못생김

 

검색하기 팁 _ 키워드를 통해서!

이럴때 이렇게 생각해보자

현재 사용하는 템플릿 엔진 : jade

템플릿 엔진을 사용하는 express

현재 망가진 것은 code

예쁘게 코드를 바꿔주는 단어는 pretty, beautiful

이 키워드를 토대로 검색해보자

jade express code pretty

검색한 결과

app.locals.pretty = true;

를 입력하면 된다고 나온다.

app.js에 입력해준 뒤

node를 재실행 시킨 뒤 확인하면 다음처럼 깔끔해진 것을 볼 수 있다.

Jade 문법 _ 태그 인식

 

템플릿에 데이터를 주입하고 싶을 때는

app.js > template를 사용하는 함수에 객체를 정의 _ 프로퍼티에 값 전달

를 사용한다

Hello를 태그로 인식한다??

반면 Jade는 텍스트로 인식한다??

제일 앞은 태그로 인식하고 그 뒤는 텍스트로 인식하는구나.

그렇다면 h1 뒤에 입력하면 되겠네

출력물과의 구분은 -

그리고 화면에 출력되는 것이 아닌 경우 앞에 -를 붙여서 구분시켜야 제대로 작동한다.

변수쓰기 _ jade변수 time

div= 처럼 div와 =을 붙여서 해야지 div = 하면 다르게 인식함

변수를 쓸 때는 붙여서 쓸 것!

여기서 궁금한게 var i를 어떻게 출력(0,1,2,3,4)시킬 수 있을까?

jade의 변수인 time을 쓰고 싶지만 쓸 수 없는 상황.

jade 내부가 아닌 jade외부에서 jade를 사용하는 express에서 변수의 값을 주입해야 한다.

app.js로 이동한 뒤 temp.jade파일을 호출하고 있는 소스에서

사용하고픈 속성명(프로퍼티)를 입력해준다.

현재는 속성명은 time이고 그 값은 hello이다.

페이지소스보기에선 오른쪽과 같이 나타나는 것을 알 수 있다.

 

다시 바꿔서 Date()로 바꿔보자

 

최종적으로 웹페이지로 표시해보면 다음과 같이 나타난다.

head태그 안에 title태그 넣고 그 안에 변수쓰기

그리고 app.js에서

temp.jade파일을 호출하는 코드를 수정한다

_title이란 속성(property)의 값을 'Jade'로 한다.

웹 페이지 소스를 실행시킨 결과는 다음과 같다.

jade 공식 사이트에서도 문법을 볼 수 있다.

최근에는 jade가 아닌 pug로 rename됨

최신버전을 사용하려면 pug를 설치할 것

https://pugjs.org/api/getting-started.html

 

쿼리스트링

사용자의 입력, 조작이 있을때 동작하는 것

입력에 따라 다른 결과를 보여줌

어떤 주소로 접근하느냐

라우터(URL)와 연결된 컨트롤러(익명함수)를 호출

빨간색은 URL의 pass부분

pass따라 다른 결과를 보여준다.

하나의 pass만으로도 다른 결과를 보여준다면?

다음처럼 하나의 pass에서 아이디만 바꿔서 나타낼 수 있다.

URL을 쪼개보면

http를 프로토콜이라고 부르고

a.com은 도메인, 서버컴 위치 주소

topic은 pass

id=1은 쿼리 스트링

그렇다면 이제 하나의 같은 pass안에서 쿼리스트링으로 다른 값을 줘보자

쿼리스트링이 포함된 링크를 만들면 쿼리스트링이 바뀜에 따라 토픽이 다르게 동작하는 웹페이지를 만들 수 있다.

(왼쪽)출력화면을 페이지소스보기로 출력했을 때(오른쪽)

 

쿼리 객체 사용

우선 하단 사진과 같은 코드를 app.js에 입력한다

(req.query.id);

req객체의 query객체에서 id라는 속성(property)을 통해서 사용자가 쿼리스트링으로 접속했을 때 전달한 정보를 사용할 수 있다.

query객체는 사용자의 쿼리스트링을 속성(현재는 id)으로 갖는다.

이렇게 해주면 id=10000으로 입력하면 10000이 출력되고 100을 입력하면 100이 출력된다. 입력한 만큼이 출력된다.

function에는 두개의 매개변수(req,res)가있다. 이 function은 우리가 아닌 express가 호출한다.

젤 오른쪽은 내가 친거
웹 페이지를 프로그래밍적으로 생성했기 때문에 나온 결과

req 문법 확인하기

위 문법이 무엇인지를 확인해보자

expressjs홈페이지에서 API > Request로 들어가자

왼쪽 바를 움직여서 req.query를 찾아서 확인해보자

위 처럼 q의 값이 곧 값이 라는 것을 알 수 있다.

 

2개의 값을 넣고 싶을 때 구분자 &을 써라

id와 name 프로퍼티 사이의 ,는 출력시 나타남. 무튼 +로 id와 name을 연결한다.

 

Query 객체의 활용

우선 다시 다음과 같은 상태로 바꾸자

다시 id 프로퍼티만 입력한 상태로 돌아온다

id값에 따라 다른 정보들이 담겨있도록 하기위해서

배열을 만들어준다.

var topics = [];

그리고 이 topics라는 배열의 값들이

id라는 프로퍼티의 값에 따라 나타날 수 있도록

res.send(topics[req.query.id]);

을 입력한다.

더 나아가

링크를 만든다.

웹 사이트에 나타난 링크를 클릭하면 해당 링크의 id프로퍼티로 이동하고 출력물도 바뀐다.

// 7.쿼리스트링편. function에는 두개의 매개변수(req,res)가있다. 이 함수는 express가 호출한다.
app.get('/topic', function(req,res){
    // 배열 만들기
    var topics = [
        'good....',
        'nice....',
        'great...'
    ];
    // 링크 그리고 변수 가진 객체만들기
    var output = `
    <a href="/topic?id=0">good?</a><br>
    <a href="/topic?id=1">nice?</a><br>
    <a href="/topic?id=2">great?</a><br>
    ${topics[req.query.id]}
    `
    res.send(output);
});

Sematic Web

이전까지는

127.0.0.1:3000/topic?id=2 를 입력했다.

그러나

이 방식은 난해해 보인다

좀 더 깔끔하게

127.0.0.1:3000/topic/2로 나타나게 할 수 있다.

이를 Semantic web이라고 한다.

WIkipedia에 Semantic Web을 검색해보면

다음과 같이 적용시켰을 전 후의 모습이 나온다

이번에는 URL을 쿼리스트링에서 pass방식으로 바꿀 것이다.

우선 현재 상태를 보자

'/topic'이기 떄문에

URL에 127.0.0.1:3000/topic/1을 입력하게되면 다음처럼 오류가 뜬다

오류가 발생하지 않게 하기 위해선

app.get('/topic/1', function()); 으로 하면 되겠지만

1이 아니라 2 혹은 1000이면? 또 오류가 뜰 것이다

그렇기 때문에

가변적으로 바뀔수 있도록 만들어야 한다.

이렇게 해주면 topic/ 뒤에 어떠한 값이 오는 URL을 입력해도 잡아준다.

그리고

topic/ 뒤에 오는 값을 application에서 req.query처럼 알아낼 수 있는 방법이 필요한데,

이 때 필요한 방법이 바로 params이다.

이를 적용시켜보자

중간 정리

Query String이 접근할 때는

req객체가 가지고 있는 query라는 객체를 사용하면 되고

pass방식으로 들어오는 Semantic URL을 사용하는 경우에는

이 id값을 받고 싶다면

을 사용하면 된다

127.0.0.1:3000/topic/1/edit 을 만들어보자

기존의 app.get('/topic/:id')는 그대로 두고

하나를 더 추가한다.

app.get('/topic/:id/:mode' function(req,res) {

res.send(req.params.id+ ' ' + req.params.mode)

})

 

//app.js 현재까지의 내용들

var express = require('express');
var app = express();
app.locals.pretty = true; // 7-1 jade소스가 웹 페이지 소스에서 깔끔하게 출력

app.set('view engine', 'jade'); // 6-1 jade템플릿 엔진과 express를 연결하는 코드

app.set('views','./views'); // 6-2.템플릿있는 디렉터리(./views) 알려줌
// jade express에선 template 파일의 이름은 views이다.
// 설령, 이 코드가 없어도 express는 기본적으로 views디렉터리를 찾음

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

// 6-3. jade 템플릿 파일 사용하기 
app.get('/template', function(req,res){
    res.render('temp',{time:Date(), _title:'Jade'}); // temp라는 템플릿 파일을 웹페이지로 렌더링해서 전송한다
    //views디렉터리 안에 temp.jade를 의미
    //우리가 6-1에서 템플릿엔진을 jade로 정의해놨기 때문에 jade의 확장자인 temp.jade를 찾아서 내부 소스를 jade문법에 맞춰 해석한 뒤 response해준다.
});

// 7-1.쿼리스트링편. function에는 두개의 매개변수(req,res)가있다. 이 함수는 express가 호출한다.
app.get('/topic/:id', function(req,res){
    // 배열 만들기
    var topics = [
        'good!! id is 0',
        'nice!! id is 1',
        'great!! id is 2'
    ];
    // 링크 그리고 변수 가진 객체만들기
    var output = `
    <a href="/topic/0">good?</a><br>
    <a href="/topic/1">nice?</a><br>
    <a href="/topic/2">great?</a><br>
    ${topics[req.params.id]} 
    ` // pass방식으로 들어오는 Semantic URL을 사용하기위해  params사용
    res.send(output);
});
// 7-2 쿼리 스트링
app.get('/topic/:id/:code', function(req,res){
    res.send(req.params.id+ ' ' + req.params.code)
});

//앱은 URL('/') 혹은 라우트에 대해 'Hello Wolrd!'로 응답
app.get('/', function (req, res) { 
    res.send('Hello World! this is homepage route');
});

app.get('/dynamic', function(req,res){
    var lis = '';
    for (var i = 0; i <5; i++){
        lis = lis + '<li>coding</li>';
    }

    var time = Date();
    var output = `
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="utf-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <title>Page Title</title>
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <link rel="stylesheet" type="text/css" media="screen" href="main.css" />
            <script src="main.js"></script>
        </head>
        <body>
            <h1>hello text guy yo man BBam</h1>
            <h2>Hello text man two guys</h2>
            <ul>
            ${lis} 
            ${time}
            </ul>
            이는 lis라는 변수를 의미한다. 
            ESC,TAB키 사이의 comma덕분에 가능한것.
            
        </body>
        </html>`;
    res.send(output);
});

app.get('/Picture',function(req,res){
    res.send('Hello This is my picture, <img src="/BurnKing.jpg">')
});

app.get('/login', function(req,res){
    res.send('<h1>Login please </h1>');
});

//앱은 서버를 시작하며 3000번 포트에 연결 청취
app.listen(3000, function (req,res) {
    // 괄호 내부의 req,res는 삭제해도 무방. 사용하지 않기때문
    // res.send('3000!'); 이 기능을 입력할 시 send는 정의되지 않았단 오류발생
    console.log('Example port 3000!');
});

정리

※ URL의 구성

Semantic We

?id= 대신 /을 사용하여 보기 쉽게 만든다.

?id= -> /

이를 쓰기위해

${res.params.변수명}을 입력

GET 방식

서버와 웹브라우저가 상호작용하는 과정에서

가장 대표적인 방식은 GET방식과 POST방식이 있다.

지금까지는 Get방식을 사용했었고

이번시간부터는 POST방식을 사용함

우선 Get방식에 대해 간략하게 설명해보자면

웹앱에 대해 정보를 얻기위해

URL을 입력해서 웹앱에 접속함

웹앱은 사용자의 요청(Request)에 따른 정보를 Response해줌

사용자는 웹앱이 Response한 정보를 가져옴(GET함)

즉, 웹브라우저에 주소를 입력해서 정보를 가져오는 것을 GET방식이라함

간혹 경우에 따라 주소에 쿼리스트링을 줘서

어떤 정보를 앱에 줘서 가져오기도 했다

이렇듯 정보를 가져오는 것을 GET방식이라 한다.

즉, 어떤 정보를 서버에 요청해서 가져오는 방식을 의미

 

POST방식

우편물을 보낸다, 전송한다.를 의미한다.

우리의 웹은 단순하게 정보를 가져오는 기능만을 담당하지 않는다.

사용자의 정보를 서버로 전송하는 기능도 있다.

로그인, 글작성 과 같은 정보를 서버로 전송하는 것.

제출양식 form _ jade로 내용 입력하기 및 입력한 내용받기

app.js에 다음 코드를 추가한다.

주석에는 POST방식이라고 쓰여져있으나 아직까진 get방식임

또한 views디렉터리에 form.jade파일을 생성하고

다음 코드를 입력한다.

속성을 넣으려면 다음처럼 괄호를 넣어라

 

제출버튼을 눌러도 입력한 정보들이 제출되지 않는다. 왜냐하면 따로 있기 떄문이다. 이들을 하나로 묶어줘야 한다.

 

form으로 묶어주면 submit해줄 수 있다. 그런데 입력한 정보들이 어디로 submit하느냐는 action으로 지정할 수 있다. 현재는 form_receiver로 전송한다. ​ ​ 전송할 액션에 해당되는 pass는 form.jade파일안에 설정한다는 점.
submit버튼을 누르면 사진처럼 url이 변경된 것을 알 수 있다.

그러나

입력한 정보들을 구분하려면 각 태그에 name을 지정해야 한다.

 

그리고 다음 내용을 입력하고 Submit을 해주면
다음처럼 쿼리스트링에 name별로 나타난다

입력된 정보를 받는 라우터 만들자

위에서 입력한 정보들은

/form_receiver로 전송된다.

이 정보들을 받을 수 있도록

/form_receiver을 만들어보자

위 코드는 입력한 텍스트들이 화면에 출력되도록 만든 것일 뿐

사용자가 전달한 값을 저장할 수 있다.

한가지 더

 

post방식으로 바꾼 뒤 submit을 하면 다음처럼 뜬다

어떠한 라우터에도 정보가 걸리지 않았음

그러나

입력한 정보들이 전송에 실패한 것은 아니다.

잘 전송됨

단지, post방식이면 데이터를 전송하는 method가 URL을 통해 데이터를 전송하지 않고

우리눈에 보이지 않는 방식으로 데이터를 전송하기에

URL에 쿼리스트링이 붙지 않은 것이다.

 

POST방식

위처럼 metho=POST인 경우

app.js에는

다음처럼

post형식의 라우터를 만들어준다.

라우터는 입력한 정보들이 전송되는 /form_receiver를 써주고

해당 기능이 실행되었을 때는

컨트롤러 function에서 Hello, POST가 뜨도록 만든다.

만약에 다시

method='get'으로 바꿔주면

app.get('/form_receiver)이 실행된다.

 

get, post 방식 비교하기

get방식으로 전송한 데이터는 익명함수가 실행될 떄 첫번째 인자인 req객체의 qeury객체의

속성인 title,description을 통해 사용자가 입력한 값을 받을 수 있었다.

req객체에 사용자가 요청한 정보가 들어간다.

이것과 똑같은 작업을 하는 app.post를 만들어보자

다음과 같이 query -> body로 바뀐 것을 알 수 있다.

 

그러나

현재 다음처럼 오류가 발생한다.

위 오류를 읽어보면

req객체가 body라는 객체를 가지지 않고 있기 때문

expressjs.com에서 API > request 를 찾아보면

기본적으로는 req.body형태가 정의되어 있지 않다는 것과 body-parser, multer라는 미들웨어를 설치해야 쓸 수 있다는 내용이 있다.

우리가 설치할 것은 body-parser인데

이는 post방식으로 전송한 데이터를 우리앱에서 사용할 수 있도록 해주는 플러그인, 확장기능모듈이다.

 

body parser 설치

이제 body-parser를 설치해보자

설치 이후

app.js에는 다음의 내용을 입력하여 body-parser를 가져오게 만든다.

위 코드에 대해 설명을 하자면

우선 require를 통해 body-parser를 추가왔다.

그리고 app.use에 입력한 코드는

앱을 통해 들어오는 모든 요청request들은

bodyParse라는 미들웨어를 통과한 뒤에

라우트가 동작한다.

항상 바디파서가 대기하다가 사용자요청따라 바디파서가 동작하면서 사용자가 포스트방식으로 전송한 데이터를 사용할 수 있도록 이 모듈이 도와준다.

이렇게 bodyparser를 추가 했으므로

입력한 정보들이 출력된다.

 

그렇다면 get,post 언제 써야하나

 

Semantic방식이 아닌 쿼리스트링방식에선

쿼리스트링방식을의 접근을 허용함

이방식에서는 get방식을 이용.

정보에 대한 주소를 나타낼 떄는 URL상에 모든 정보를 포함시켜야 한다.

 

만약에

그런데 이와 같은 상황에서

아이디와 비밀번호를 입력해야 한다면?

모든 정보들이 URL상에 나타나게 된다

GET방식

이와 같은 상황에선 URL상에 정보들이 나타나지 않는 POST방식을 써야한다.

POST방식

그러나 POST방식도 보안적으로 불안정한 방식이다.

다시

GET에 대해 얘기해보자

URL, 쿼리스트링을 통해 정보를 전달하는 경우,

굉장히 긴 글을 입력하여 get방식으로 전달하는 경우,

그 정보가 굉장히 크면 URL규격상 정보를 버린다.

고로 이렇게 전송해선 안된다.

온전히 입력 전체 데이터가 전송되려면 전송방법을 POST로 지정해야한다.

즉, POST는 용량제한이 없다

반응형