[ File System ]
클라이언트가 보내고자 하는 정보를 담아 서버에 요청하면, 서버는 그 정보를 저장하고 페이지를 통해 응답할 수 있습니다. 그 응답은 당연하게도 그 저장된 정보를 그대로 보여줄 수도 있죠. Express가 제공하는 File System을 이용하면 됩니다.
//Web Aplication
//module
const express = require('express');
const app = express();
const fs = require('fs')
//listening
app.listen(3000, function(){
console.log('connected!')
})
다음과 같이 'fs'라는 이름을 가진 File system 모듈을 불러올 수 있습니다. 이제 저 모듈을 사용해 서버에 있는 파일을 불러올 수 있고, 클라이언트가 요청한 정보를 파일로 저장할 수 있습니다.
topic이라는 페이지에 서버의 특정폴더에 있는 파일들의 이름을 나열해 보겠습니다. 서버의 특정 폴더로 접근하려면 fs.readdir이라는 메서드가 필요합니다.
fs.readdir('<your page path>', function(err,files){ });
콜백함수에는 err라는 에러를 표시해주는 매개변수와 files라는 파일이름을 표시해주는 매개변수가 들어있습니다.
이제 topic 페이지를 보여주는 라우터를 만들고 list를 보여줄 수 있는 jade파일을 만들어보겠습니다.
먼저 파일들이 들어가 있는 폴더를 data_file로 만들고 그 안에 텍스트가 적힌 파일을 넣습니다. list를 보여줄 수 있는 jade파일입니다.
doctype html
html
head
meta(charset = 'utf-8')
body
h1 List of Contents
ul
each topic in topics
li
a(href = '/topic/'+topic)= topic
h2= title
h3= contents
topics라는 리스트에서 반복문이 돌고 있습니다. file이름을 li > a 태그로 만들고 파일이름으로 끝나는 링크를 걸어뒀습니다. topics는 전체 파일의 이름과 대치대므로 라우터에서 설정해줍니다.
app.set('views', './views_file');
app.set('view engine', 'jade');
app.locals.pretty = true;
app.get('/topic',function(req,res){
fs.readdir('data_file', function(err,files){
if(err){
console.log(err);
res.send('Error')
}
res.render('list',{topics:files});
})
})
이렇게 하면 "라우터에서 views_file/list라는 jade파일을 랜더링 하는데, file이름들을 jade파일에서 topics라는 변수로 사용하겠다." 라는 의미가 됩니다. (res.render('list', {topics:files}); 부분)
이제 링크를 누르면 해당 글을 볼 수 있는 페이지( "/topic/<file name>")으로 이동시켜보겠습니다. 그 전에 파일별로 표시되는 내용이 다르므로 해당 고유 경로가 있어야 하겠죠.
파일을 읽는 메서드는 다음과 같습니다.
fs.readFile('<path of file>', 'utf-8', function(err, data){ });
app.get('/topic/:id', function(req,res){
const id = req.params.id;
fs.readFile('data_file/'+id, 'utf-8',function(err,data){
if(err){
console.log(err);
res.send('Error')
}
res.send(data);
})
})
위 jade파일에서 "파일이름이 뒤에 붙는 링크"로 이동하게 작업을 걸어뒀습니다. 그리고 readFile 메서드를 통해 그 링크에서 나타나는 정보는 data_file이라는 폴더에 있는 파일들의 내용들이 보여지게 만들었습니다.
이 모든걸 하나의 화면에서 내용만 바뀌는 페이지로 바꾸고 싶다면, /topic을 get하는 라우터는 파일의 리스트만, /topic/:id의 페이지는 파일의 리스트 + 내용을 넣어주면 페이지가 더 세련되게 바뀝니다.
//Web Aplication
//module
const express = require('express');
const app = express();
const fs = require('fs')
//listening
app.listen(3000, function(){
console.log('connected!')
})
//template engine
app.set('views', './views_file');
app.set('view engine', 'jade');
app.locals.pretty = true;
//routes
app.get('/topic',function(req,res){
fs.readdir('data_file', function(err,files){
if(err){
console.log(err);
res.send('Error')
}
res.render('list',{topics:files});
})
})
app.get('/topic/:id', function(req,res){
const id = req.params.id;
fs.readdir('data_file', function(err,files){
if(err){
console.log(err);
res.send('Error')
}
fs.readFile('data_file/'+id, 'utf-8', function(err,data){
if(err){
console.log(err);
res.status(500).send('Error');
}
res.render('list', {topics:files, title:id, contents:data});
})
})
})
post를 이용해 새로운 파일을 만드는 라우터를 만들 수 있습니다. 파일을 쓰는 메서드는 다음과 같습니다.
fs.writeFile('<path of file(name)>', <description>, function(err){ });
파일을 저장할 폴더가 있어야 동작합니다.
그리고 /topic/:id와 /topic get하는 두개의 라우터가 겹치는 부분이 있으므로 if문으로 하나의 라우터로 처리할 수 있습니다. post를 통해 정보를 전달받는 방식은 http://twoearth.tistory.com/39을 참고하세요. post를 통해 정보와 함께 들어온 요청에서 제목과 내용을 파일로 저장하면 됩니다.
//Web Aplication
//module
const express = require('express');
const app = express();
const fs = require('fs')
//listening
app.listen(3000, function(){
console.log('connected!')
})
//midleware(for post method)
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({extended : false}))
//template engine
app.set('views', './views_file');
app.set('view engine', 'jade');
app.locals.pretty = true;
//routes
app.get('/topic/new', function(req,res){
res.render('new');
})
app.post('/topic', function(req,res){
const title = req.body.title;
const contents = req.body.contents;
fs.writeFile('data_file/'+title, contents, function(err){
if(err){
console.log(err)
res.status(500).send('Error');
}
res.send('Success!')
})
})
app.get(['/topic', '/topic/:id'],function(req,res){
const id = req.params.id;
fs.readdir('data_file', function(err,files){
if(err){
console.log(err);
res.send('Error')
}
// id가 있을 때
if(id){
fs.readFile('data_file/'+id, 'utf-8', function(err,data){
if(err){
console.log(err);
res.status(500).send('Error');
}
res.render('list', {topics:files, title:id, contents:data});
})
}
// id가 없을 때
else{
res.render('list',{topics:files});
}
})
})