템플릿 양식과 특정 데이터 모델에 따른 입력 자료를 합성하여 결과 문서를 출력하는 소프트웨어(또는 소프트웨어 컴포넌트)를 말한다.
그 중 웹 템플릿 엔진(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를 찾아서 확인해보자
2개의 값을 넣고 싶을 때 구분자 &을 써라
Query 객체의 활용
우선 다시 다음과 같은 상태로 바꾸자
id값에 따라 다른 정보들이 담겨있도록 하기위해서
배열을 만들어준다.
var topics = [];
그리고 이 topics라는 배열의 값들이
id라는 프로퍼티의 값에 따라 나타날 수 있도록
res.send(topics[req.query.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에 다음 코드를 추가한다.
또한 views디렉터리에 form.jade파일을 생성하고
다음 코드를 입력한다.
그러나
입력한 정보들을 구분하려면 각 태그에 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는 용량제한이 없다
'○ WEB > 19.06 생활코딩_Node.js' 카테고리의 다른 글
2. JS 기본학습 (0) | 2019.09.06 |
---|---|
개발 스택 JSP, Spring boot , node.js (0) | 2019.07.17 |
Node.js? 웹서버? API서버 (0) | 2019.07.17 |
2. Express란? install / Connection / 정적파일서비스 / 웹페이지 표현하는 법 (0) | 2019.06.28 |
1. Node.js란? / 설치 / 웹 구조, 포트 / 모듈 / NPM, uglify install / npm module, underscore, dependency / Callback, 익명함수 / 동기와 비동기 (0) | 2019.06.28 |