인터넷의 동작 방법
npm
callback
동기, 비동기
템플릿 엔진
관례로, views 라는 디렉토리 안에서 템플릿 엔진을 관리한다. (ejs, jade 등등)
app.js 에서 아래 코드 설정
app.set('view engine', 'ejs');
app.set('views', './views');
Render 의 두번째 인자로 json 형식의 데이터를 넘길 수 있고, 템플릿 엔진에서 그것을 받아서 사용가능
// views/temp.ejs
<html>
<head>
<title>plating</title>
</head>
<body>
hello plating
<p><%= time %></p>// 변수 설정은 요런 식으로
</body>
</html>//app.js
var express = require('express');
var app = express();
...
app.get('/template', function(req, res){
res.render('temp', {time:Date()});//time변수에 현재시간이 할당된다.
});Query string
Ex) http://a.com/topic?id=3 의 ?id=3 부분.
//app.js
app.get('/topic', function(req, res){
res.send(req.query.id);
}); // 3출력참고 : http://expressjs.com/ko/api.html#req
//req.query
// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret"
// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
req.query.order
// => "desc"
req.query.shoe.color
// => "blue"
req.query.shoe.type
// => "converse"
// app.js
app.get('/topic', function(req, res){
var topics = [
'Javascript is ...',
'Nodejs is ...',
'Express is ...'
];
var output = `
<a href="/topic?id=0">Javascript</a><br>
<a href="/topic?id=1">Nodejs</a><br>
<a href="/topic?id=2">Express</a><br><br>
${topics[req.query.id]}
`
res.send(output);
});시멘틱 URL
// app.js
// 시멘틱 URL을 사용할 때.
app.get('/topic/:id', function(req, res){ // :id로 바꾸어 주어야 한다.
var topics = [
'Javascript is ...',
'Nodejs is ...',
'Express is ...'
];
var output = `
<a href="/topic/0">Javascript</a><br>
<a href="/topic/1">Nodejs</a><br>
<a href="/topic/2">Express</a><br><br>
// req.query 대신 req.param을 써야한다.(파라미터 줄임말)
${topics[req.params.id]}
`
res.send(output);
});
app.get('/topic/:id/:mode', function(req, res){
res.send(req.params.id+','+req.params.mode);
});// app.js
app.get('/form', function(req, res){
res.render('form');
});
app.get('/form_receiver', function(req, res){
var title = req.query.title;
var description = req.query.description;
res.send(title+','+description);
});// form.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>form</title>
</head>
<body>
<form action="/form_receiver" method="get">
hello it is form
<p><input type="text" name="title"></p>
<p><textarea name="description"></textarea></p>
<p><input type="submit"></p>
<form>
</body>
</html>form은 html에서 url을 생성해 주는 작은 프로그램.
위의 코드는 get 방식이기에, querystring을 통해 데이터가 노출된다. Post 방식을 사용하여, 데이터를 보호해야한다.
데이터를 전송하는 방법이 post이면, url을 통해서 데이터를 전송하지 않고, 우리 눈에 보이지 않는 방법으로 데이터를 전송한다.(url에 query string이 붙지 않는다.)
그럼, post 방식으로 전송한 데이터는 어떻게 받을 수 있나?
(get 방식은 request객체의 query객체의 title,description으로 사용자가 요청한 데이터를 받을 수 있었다.)
post는 query가 아니라, body이다.
// app.js
app.get('/form_receiver', function(req, res){
var title = req.query.title;
var description = req.query.description;
res.send(title+','+description);
});
app.post('/form_receiver', function(req, res){
var title = req.body.title;
var description = req.body.description;
res.send(title+','+description);
});그래서 위 처럼 해보았는데, 안된다.(reqest에 body가 없단다.)
그럴땐 문서를 보자 ㅋㅋ http://expressjs.com/ko/api.html#req.body bodyParser 뭐시기가 필요하단다 ㅋㅋ
bodyParser 또는 multer 라는 미들웨어가 필요함.
//app.js
app.use(bodyParser.urlencoded({ extended: false }));//post 방식으로 들어온 데이터를 사용할 수 있게 하는 미들웨어
...
app.post('/form_receiver', function(req, res){
var title = req.body.title;
var description = req.body.description;
res.send(title+','+description);
});요렇게 해야한다 ㅋㅋ
BodyParser는 사용자가 post 방식으로 전송한 데이터를 request객체에 request객체가 가지고 있지 않던 body라는 객체를 추가한다.
// app.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var fs = require('fs');
app.use(bodyParser.urlencoded({ extended: false }));
app.set('views', './views');
app.set('view engine', 'ejs');
app.get('/menus/new', function(req, res){ //순서가 중요한것 같다...
fs.readdir('data',function(err, files){
if(err) throw err;
res.render("new", {menus:files});
});
});
app.get(['/menus', '/menus/:id'],function(req, res){
fs.readdir('data',function(err, files){
if(err) throw err;
var id = req.params.id;
if(id){
fs.readFile('data/'+id, 'utf8', function(err, data){
if(err) console.log(err);
res.render('view', {menus:files, title:id, description:data});
});
} else {
res.render("view", {menus:files, title:'welcome to plating', description: 'enjoy your meal!'});
}
});
});
app.post('/menus', function(req, res){
var title = req.body.title;
var description = req.body.description;
fs.writeFile('data/'+title, description, (err) => {
if(err) res.status(500).send('Internal Server Error');
console.log("The file has been saved!");
res.redirect('/menus/'+title);
});
});
app.listen(8080, function(){
console.log("Connected at 8080");
});// new.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add menu</title>
</head>
<body>
<h1>plating menu list</h1>
<ol>
<% for(var i = 0; i<menus.length; i++){%>
<li>
<a href='/menus/<%= menus[i] %>'>
<%= menus[i]%>
</a>
</li>
<% } %>
</ol>
<h3>New menu</h3>
<form action="/menus" method="post">
<p><input type="text" name="title" placeholder="title"></p>
<p><textarea name="description"></textarea></p>
<p><input type="submit"></p>
</form>
</body>
</html>// view.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>plaing menu</title>
</head>
<body>
<h1>plating menu list</h1>
<ol>
<% for(var i = 0; i<menus.length; i++){%>
<li>
<a href='/menus/<%= menus[i] %>'>
<%= menus[i]%>
</a>
</li>
<% }; %>
</ol>
<article>
<h2><%= title %></h2>
<p><%= description %></p>
</article>
<div>
<a href="/menus/new">new menu</a>
</div>
</body>
</html>