목차
multer 란?
- Node.js에서 파일 업로드를 처리하기 위해 사용되는 미들웨어
- express로 서버를 구축할 때 가장 많이 사용되는 미들웨어
설치
npm install multer express
사용법 - Form 태그
하나의 인풋에 하나의 파일을 업로드
views/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>폼 전송</title>
</head>
<body>
<h1>Single file upload</h1>
<p>하나의 인풋에 하나의 파일을 업로드</p>
<!-- multer는 multipart가 아닌 폼에서는 동작하지 않음! 따라서 enctype="multipart/form-data" 속성 필수~ -->
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="userfile" /><br />
<button type="submit">업로드</button>
</form>
</body>
</html>
app.js
const express = require('express');
const multer = require('multer');
const app = express();
const PORT = 3000;
const path = require('path');
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// multer 관련 설정
const upload = multer({
// storage: 저장할 공간에 대한 정보
// done(null, xx) 여기서 null은 error를 의미하는 매개변수
// 에러가 없으므로 "null"이라고 전달하여 콜백 함수를 호출!
storage: multer.diskStorage({
destination(req, file, done) {
// done: callback
done(null, 'uploads/'); // 파일을 업로드할 경로 설정
},
filename(req, file, done) {
const ext = path.extname(file.originalname); // 파일 "확장자"를 추출
done(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
// limits: 파일 제한 정보
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
});
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/views/index.html'));
});
// 'userfile' = 클라이언트 <input type="file" name="userfile" /> 태그 name 값
app.post('/upload', upload.single('userfile'), (req, res) => {
console.log(req.body); // 파일 외의 정보들
console.log(req.file); // 파일 업로드 정보
// 파일 업로드 처리 후 응답
res.send('파일 업로드 완료!');
});
app.listen(PORT, () => {
console.log('연결 성공');
});
하나의 인풋에 여러 개의 파일을 업로드
views/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>폼 전송</title>
</head>
<body>
<h1>Multi file upload v1</h1>
<p>하나의 인풋에 여러 개의 파일을 업로드</p>
<form action="/upload/array" method="POST" enctype="multipart/form-data">
<!-- 하나의 인풋에 여러 파일을 입력받고 싶다면 multiple 속성을 추가 -->
<input type="file" name="userfiles" multiple /><br />
<button type="submit">업로드</button>
</form>
</body>
</html>
app.js
const express = require('express');
const multer = require('multer');
const app = express();
const PORT = 3000;
const path = require('path');
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// multer 관련 설정
const upload = multer({
// storage: 저장할 공간에 대한 정보
// done(null, xx) 여기서 null은 error를 의미하는 매개변수
// 에러가 없으므로 "null"이라고 전달하여 콜백 함수를 호출!
storage: multer.diskStorage({
destination(req, file, done) {
// done: callback
done(null, 'uploads/'); // 파일을 업로드할 경로 설정
},
filename(req, file, done) {
const ext = path.extname(file.originalname); // 파일 "확장자"를 추출
done(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
// limits: 파일 제한 정보
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
});
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/views/index.html'));
});
app.post('/upload/array', upload.array('userfiles'), (req, res) => {
console.log(req.files); // [ { 파일1_정보 }, { 파일2_정보 }, .. ] : 배열 형태로 각 파일 정보를 출력
console.log(req.body);
res.send('하나의 인풋에 여러 파일 업로드 완료!');
});
app.listen(PORT, () => {
console.log('연결 성공');
});
여러 인풋에 각각의 파일을 업로드
views/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>폼 전송</title>
</head>
<body>
<h1>Multi file upload v2</h1>
<p>여러 인풋에 각각의 파일을 업로드</p>
<form action="/upload/fields" method="POST" enctype="multipart/form-data">
<input type="file" name="userfile1" /><br />
<input type="file" name="userfile2" /><br />
<button type="submit">업로드</button>
</form>
</body>
</html>
app.js
const express = require('express');
const multer = require('multer');
const app = express();
const PORT = 3000;
const path = require('path');
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// multer 관련 설정
const upload = multer({
// storage: 저장할 공간에 대한 정보
// done(null, xx) 여기서 null은 error를 의미하는 매개변수
// 에러가 없으므로 "null"이라고 전달하여 콜백 함수를 호출!
storage: multer.diskStorage({
destination(req, file, done) {
// done: callback
done(null, 'uploads/'); // 파일을 업로드할 경로 설정
},
filename(req, file, done) {
const ext = path.extname(file.originalname); // 파일 "확장자"를 추출
done(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
// limits: 파일 제한 정보
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
});
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/views/index.html'));
});
// fields() 매개 변수로 input 태그의 name을 각각 넣기
app.post('/upload/fields', upload.fields([{ name: 'userfile1' }, { name: 'userfile2' }]), (req, res) => {
console.log(req.files); // { userfile1: [ {파일_정보} ], userfile2: [ {파일_정보} ]} 객체 안에 배열 형태로 각 파일 정보
console.log(req.body);
res.send('하나의 인풋에 여러 파일 업로드 완료!');
});
app.listen(PORT, () => {
console.log('연결 성공');
});
사용법 - fetch API
views/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>폼 전송</title>
</head>
<body>
<h1>동적 파일 업로드</h1>
<form>
<input type="file" name="dynamicUserfile" id="dynamic-file" /><br />
<button type="submit" class="btn">업로드</button>
</form>
<!-- 업로드한 이미지를 보여줄 img 태그 요소 -->
<img src="" alt="" width="400" />
<script>
const btn = document.querySelector('.btn');
btn.addEventListener('click', (e) => {
e.preventDefault();
console.log('동적 파일 업로드');
// js 만으로 폼을 전송 (파일데이터를 서버로 전송해야 하는 케이스)
// FormData 객체를 활용하면 쉽게 전송 가능!
const formData = new FormData();
const file = document.querySelector('#dynamic-file');
console.dir(file);
console.dir(file.files); // 업로드한 파일 객체
console.dir(file.files[0]); // 업로드한 첫 파일
// append(key, value)
formData.append('dynamicUserfile', file.files[0]);
fetch('/dynamicFile', {
method: 'post',
header: {
'Content-Type': 'multipart/form-data', // enctype="multipart/form-data"
},
body: formData
}).then((response) => {
return response.json();
}).then((data) => {
console.log(data);
document.querySelector('img').src = '/' + data.path;
});
});
</script>
</body>
</html>
app.js
const express = require('express');
const multer = require('multer');
const app = express();
const PORT = 3000;
const path = require('path');
app.use('/uploads', express.static(__dirname + '/uploads'));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// multer 관련 설정
const upload = multer({
// storage: 저장할 공간에 대한 정보
// done(null, xx) 여기서 null은 error를 의미하는 매개변수
// 에러가 없으므로 "null"이라고 전달하여 콜백 함수를 호출!
storage: multer.diskStorage({
destination(req, file, done) {
// done: callback
done(null, 'uploads/'); // 파일을 업로드할 경로 설정
},
filename(req, file, done) {
const ext = path.extname(file.originalname); // 파일 "확장자"를 추출
done(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
// limits: 파일 제한 정보
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
});
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/views/index.html'));
});
// 동적 폼 전송
app.post('/dynamicFile', upload.single('dynamicUserfile'), (req, res) => {
console.log(req.file);
res.send(req.file);
});
app.listen(PORT, () => {
console.log('연결 성공');
});
반응형