multer : Express를 이용해서 사용자가 전송한 데이터 파일을 어딘가에 저장하는데에 최적화된 모듈
npm install --save multer
이 multer를 사용하기 위해서는 따로 설치가 필요하다.
var multer = require('multer');
multer모듈을 사용하기 위해 변수를 선언한다.
app.get('/upload', function (req, res) {
res.render('upload');
});
다음과 같이 프레임을 만들어주고 views 디렉토리 내에 upload.pug 파일을 생성해준다.
doctype html
html
head
meta(charset='utf-8')
body
form(action='upload' method='post' enctype="multipart/form-data")
이렇게 upload.pug 파일을 생성했다면 여기서 중요한 속성이 있다.
바로 enctype="multipart/form-data" 부분이다.
이 속성을 주어야 사용자가 전송한 데이터를 서버로 전송할 수 있다.
input(type='file' name='userfile')
input(type='submit')
파일 선택 버튼과 제출 버튼을 만들어준다.
여기까지 작성하고 파일을 선택한 다음, 제출 버튼을 누르면 Cannot POST /upload의 에러가 뜰 것이다.
그러므로 /upload에 해당하는 라우터를 만들어줘야한다.
app.post('/upload', function (req, res) {
res.send('Uploaded');
});
메서드를 post방식으로 설정하였고, post로 접근한 사용자의 정보를 받기 위해 post방식의 라우터를 만든다.
사용자가 전송한 파일을 서버의 어떤 위치에 저장해야한다.
과연 어떤 방식으로 저장을 해야할까?
그 전에 변수 선언을 한가지 더 해야한다.
var upload = multer({dest: 'uploads/'});
multer라는 모듈은 사실 함수이기 때문에 해당 함수에 dest: 'uploads/'라는 옵션을 주고 실행시키면, 이 함수는 업로드를 받아낼 수 있는 미들웨어를 리턴하게 된다.
여기서 dest는 destination(목적지)의 줄임말이다. 사용자가 업로드한 파일이 애플리케이션의 디렉토리 중 어디에 최종적으로 저장되어야할지 지정하는 설정값이다.
파일이 저장될 때, 파일의 이름이 랜덤으로 결정돼서 저장된다.
app.post('/upload', upload.single('userfile'), function (req, res) {
res.send('Uploaded');
});
사용자가 post방식으로 전송한 데이터가 upload라는 디렉토리를 향하고 있다면 res.send('Uploaded');를 실행시킨다.
이 때, function이 실행되기 전에 미들웨어인 upload가 갖고 있는 upload.single('avatar')가 먼저 실행된다.
upload.single('avatar') : 사용자가 전송한 데이터에 만약 파일이 포함되어 있다면 그 파일을 가공해서 req객체의 file이라는 property를 암시적으로 추가하도록 약속되어있는 미들웨어이다.
파일 이름을 원본 그대로 저장하기 위해 dest대신 storage라는 property를 사용할 것이다.
var _storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
})
var upload = multer({storage: _storage});
storage 변수를 선언하고 속성값도 storage라고 변경해준다.
위의 코드를 더 자세히 살펴보자.
{
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
}
부분은 객체의 정보를 담고 있는 것이다. 객체는 크게 2개의 property를 갖고 있는데 첫번째는 저장위치(Path), 두번째는 저장할 파일이름(파일명)이다.
추가로 사용자가 업로드한 이미지를 웹애플리케이션 내에서 출력하고자 한다면 다음과 같이 설정해주면 된다.
app.use('/user', express.static('uploads'));
그러면 사용자는 /user 경로로 접근해서 uploads 디렉토리 내에 있는 파일을 볼 수 있다.
예를 들어 uploads에 저장된 test.jpg 파일을 보고 싶다면 /user/test.jpg 라고 입력하면 된다.
<new.pug 전체코드>
doctype html
html
head
meta(charset='utf-8')
body
h1
a(href='/topic') Server Title
ul
each topic in topics
li
a(href='/topic/' + topic)= topic
article
form(action='/topic' method='post')
p
input(type='text', name='title' placeholder='title')
p
textarea(name='description')
p
input(type='submit')
<upload.pug 전체코드>
doctype html
html
head
meta(charset='utf-8')
body
form(action='upload' method='post' enctype="multipart/form-data")
input(type='file' name='userfile')
input(type='submit')
<view.pug 전체코드>
doctype html
html
head
meta(charset='utf-8')
body
h1
a(href='/topic') Server Title
ul
each topic in topics
li
a(href='/topic/'+topic)= topic
article
h2= title
= description
div
a(href='/topic/new') new
<app.js 전체코드>
var express = require('express');
var bodyParser = require('body-parser');
var multer = require('multer');
var _storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
})
var upload = multer({storage: _storage});
var fs = require('fs');
var app = express();
app.use(bodyParser.urlencoded({extended: false}));
app.locals.pretty = true;
app.use('/user', express.static('uploads'));
app.set('views', './views');
app.set('view engine', 'pug');
app.get('/upload', function (req, res) {
res.render('upload');
});
app.post('/upload', upload.single('userfile'), function (req, res) {
console.log(req.file);
res.send('Uploaded : ' + req.file.filename);
});
app.get('/topic/new', function (req, res) {
fs.readdir('data', function (err, files) {
if (err) {
console.log(err);
res.status(500).send('Internal Server Error');
}
res.render('new', {topics: files});
})
});
app.get(['/topic', '/topic/:id'], function (req, res) {
fs.readdir('data', function (err, files) {
if (err) {
console.log(err);
res.status(500).send('Internal Server Error');
}
var id = req.params.id;
if (id) {
// id값이 있을 때
fs.readFile('data/' + id, 'utf-8', function (err, data) {
if (err) {
console.log(err);
res.status(500).send('Internal Server Error');
}
res.render('view', {topics: files, title: id, description: data});
})
} else {
// id값이 없을 때
res.render('view', {topics: files, title: 'Welcome', description: 'Hello, JavaScript for server.'});
}
})
});
app.post('/topic', function (req, res) {
var title = req.body.title;
var description = req.body.description;
fs.writeFile('data/' + title, description, function (err) {
if (err) {
console.log(err);
res.status(500).send('Internal Server Error');
}
res.redirect('/topic/' + title);
});
});
app.listen(7777, function () {
console.log('Connected, 7777 port!');
});
'javascript > node.js 웹애플리케이션 제작' 카테고리의 다른 글
[Node.js] 자바스크립트 데이터베이스 연동 - 웹애플리케이션 2 (0) | 2024.07.13 |
---|---|
[Node.js] 자바스크립트 데이터베이스 연동 - 웹애플리케이션 1 (0) | 2024.07.13 |
[Node.js] 웹애플리케이션 제작 - 3 코드 개선 (0) | 2024.07.09 |
[Node.js] 웹애플리케이션 제작 - 2 (0) | 2024.07.09 |
[Node.js] 웹애플리케이션 제작 - 1 (0) | 2024.07.09 |