ํ์ผ ์ ๋ก๋๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ฃผ ์ฌ์ฉ๋๋ ๊ธฐ๋ฅ ์ค ํ๋์ ๋๋ค. Node.js์์๋ ํ์ผ ์ ๋ก๋๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ํ์ผ ์ฒ๋ฆฌ ๋ชจ๋๊ณผ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํด ์ฝ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค. ์ด ๊ธ์์๋ Node.js์์ ํ์ผ ์ ๋ก๋๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋จ๊ณ๋ณ๋ก ์ค๋ช ํ๊ณ , ์ด๋ฅผ ํ์ฉํ ๊ฐ๋จํ ํ์ผ ์ ๋ก๋ ์๋ฒ๋ฅผ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํฉ๋๋ค.
ํ์ผ ์ ๋ก๋ ์ฒ๋ฆฌ์ ํ์ํ ํจํค์ง
Node.js์์ ํ์ผ ์
๋ก๋๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด์๋ ๋ช ๊ฐ์ง ํจํค์ง๊ฐ ํ์ํฉ๋๋ค. ์ฌ๊ธฐ์์๋ express
ํ๋ ์์ํฌ์ ํ์ผ ์
๋ก๋๋ฅผ ์ฒ๋ฆฌํ๋ multer
ํจํค์ง๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- Express: ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ Node.js ํ๋ ์์ํฌ
- Multer: multipart/form-data ํ์์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฏธ๋ค์จ์ด๋ก, ํ์ผ ์ ๋ก๋์ ์ฌ์ฉ
ํ์ํ ํจํค์ง ์ค์น
๋จผ์ , ํ๋ก์ ํธ ํด๋๋ฅผ ์์ฑํ ํ ํ์ํ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค.
$ npm init -y
$ npm install express multer
์ ๋ช
๋ น์ด๋ฅผ ์คํํ๋ฉด express
์ multer
ํจํค์ง๊ฐ ์ค์น๋๋ฉฐ, ํ์ผ ์
๋ก๋ ์ฒ๋ฆฌ๋ฅผ ์ํ ๊ธฐ๋ณธ ์ค๋น๊ฐ ์๋ฃ๋ฉ๋๋ค.
Express ์๋ฒ์์ ํ์ผ ์ ๋ก๋ ์ฒ๋ฆฌํ๊ธฐ
์ด์ Express ์๋ฒ๋ฅผ ์ค์ ํ๊ณ , multer
๋ฅผ ์ฌ์ฉํด ํ์ผ ์
๋ก๋ ๊ธฐ๋ฅ์ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค.
1. Express ์๋ฒ ์ค์
๊ฐ๋จํ Express ์๋ฒ๋ฅผ ์ค์ ํฉ๋๋ค. ํ์ผ ์ ๋ก๋ ๊ฒฝ๋ก์ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋๋ก ๋ผ์ฐํธ๋ฅผ ์ค์ ํฉ๋๋ค.
// app.js
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
// ํ์ผ ์ ์ฅ ์์น ๋ฐ ํ์ผ๋ช
์ค์
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/'); // ์
๋ก๋ ํด๋ ๊ฒฝ๋ก
},
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname)); // ํ์ผ๋ช
์ค์
}
});
const upload = multer({ storage: storage });
app.use(express.static('public')); // ์ ์ ํ์ผ ์ ๊ณต (HTML ํ์ผ ์์น)
// ํ์ผ ์
๋ก๋ ์ฒ๋ฆฌ ๋ผ์ฐํธ
app.post('/upload', upload.single('file'), (req, res) => {
res.send('ํ์ผ ์
๋ก๋๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค.');
});
// ์๋ฒ ์คํ
app.listen(3000, () => {
console.log('์๋ฒ๊ฐ http://localhost:3000 ์์ ์คํ ์ค์
๋๋ค.');
});
์ ์ฝ๋๋ ๊ฐ๋จํ Express ์๋ฒ๋ฅผ ์ค์ ํ ๊ฒ์
๋๋ค. multer
๋ฅผ ์ฌ์ฉํ์ฌ ํ์ผ ์
๋ก๋๋ฅผ ์ฒ๋ฆฌํ๋ฉฐ, ํ์ผ์ uploads
ํด๋์ ์ ์ฅ๋ฉ๋๋ค. ํ์ผ ์ด๋ฆ์ ์
๋ก๋ ์ Date.now()
๋ฅผ ์ฌ์ฉํด ํ์ฌ ์๊ฐ์ผ๋ก ์ค์ ๋์ด ์ค๋ณต๋์ง ์๋๋ก ํฉ๋๋ค.
2. ํ์ผ ์ ๋ก๋ ํด๋ ์์ฑ
ํ์ผ์ด ์ ์ฅ๋ uploads
ํด๋๋ฅผ ํ๋ก์ ํธ ๋๋ ํฐ๋ฆฌ์ ์์ฑํฉ๋๋ค.
$ mkdir uploads
3. HTML ํ์ผ ์์ฑ
ํด๋ผ์ด์ธํธ์์ ํ์ผ์ ์ ๋ก๋ํ ์ ์๋ ๊ฐ๋จํ HTML ์์์ ์์ฑํฉ๋๋ค. ์ด ์์์ ํตํด ์ฌ์ฉ์๊ฐ ํ์ผ์ ์ ํํ๊ณ ์ ๋ก๋ํ ์ ์์ต๋๋ค.
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ํ์ผ ์
๋ก๋</title>
</head>
<body>
<h1>ํ์ผ ์
๋ก๋</h1>
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<button type="submit">์
๋ก๋</button>
</form>
</body>
</html>
์ด HTML ํ์ผ์ ์ฌ์ฉ์๊ฐ ํ์ผ์ ์ ํํ๊ณ ์๋ฒ๋ก ์
๋ก๋ํ ์ ์๋ ๊ธฐ๋ณธ ์์์ ์ ๊ณตํฉ๋๋ค. enctype="multipart/form-data"
์์ฑ์ ํ์ผ ์
๋ก๋๋ฅผ ์ํ ํ์ ์ค์ ์
๋๋ค.
4. ์๋ฒ ์คํ ๋ฐ ํ์ผ ์ ๋ก๋ ํ ์คํธ
์ด์ ์๋ฒ๋ฅผ ์คํํ๊ณ , ๋ธ๋ผ์ฐ์ ์์ ํ์ผ์ ์ ๋ก๋ํ ์ ์๋์ง ํ์ธํด๋ด ๋๋ค.
$ node app.js
์๋ฒ๊ฐ ์คํ๋๋ฉด ๋ธ๋ผ์ฐ์ ์์ http://localhost:3000
์ผ๋ก ์ด๋ํ์ฌ ํ์ผ ์
๋ก๋ ์์์ ํ์ธํ ์ ์์ต๋๋ค. ํ์ผ์ ์ ํํ ํ ์
๋ก๋๋ฅผ ํด๋ฆญํ๋ฉด, ์๋ฒ๋ ํ์ผ์ ์ฒ๋ฆฌํ๊ณ uploads
ํด๋์ ์ ์ฅํฉ๋๋ค. ํ์ผ ์
๋ก๋๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋๋ฉด, ๋ธ๋ผ์ฐ์ ์ ์
๋ก๋ ์๋ฃ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
Multer ์ต์ : ํ์ผ ํฌ๊ธฐ ์ ํ ๋ฐ ํํฐ๋ง
multer
๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ผ ํฌ๊ธฐ ์ ํ์ด๋ ํ์ผ ์ ํ์ ํํฐ๋งํ๋ ๋ฑ ๋ค์ํ ์ต์
์ ์ค์ ํ ์ ์์ต๋๋ค.
ํ์ผ ํฌ๊ธฐ ์ ํ
์
๋ก๋ํ ํ์ผ์ ํฌ๊ธฐ๋ฅผ ์ ํํ๋ ค๋ฉด limits
์ต์
์ ์ค์ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํ์ผ ํฌ๊ธฐ๋ฅผ 2MB๋ก ์ ํํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const upload = multer({
storage: storage,
limits: { fileSize: 2 * 1024 * 1024 } // ํ์ผ ํฌ๊ธฐ ์ ํ: 2MB
});
ํ์ผ ํ์ ํํฐ๋ง
ํน์ ํ์ผ ํ์๋ง ์
๋ก๋ํ ์ ์๋๋ก ์ ํํ๋ ค๋ฉด fileFilter
์ต์
์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ ์ฝ๋๋ ์ด๋ฏธ์ง ํ์ผ(JPG, PNG)๋ง ํ์ฉํ๋ ํํฐ๋ง ๋ฐฉ๋ฒ์
๋๋ค.
const upload = multer({
storage: storage,
fileFilter: (req, file, cb) => {
const fileTypes = /jpeg|jpg|png/;
const mimeType = fileTypes.test(file.mimetype);
const extname = fileTypes.test(path.extname(file.originalname).toLowerCase());
if (mimeType && extname) {
return cb(null, true);
} else {
cb(new Error('์ด๋ฏธ์ง ํ์ผ๋ง ์
๋ก๋ ๊ฐ๋ฅํฉ๋๋ค.'));
}
}
});
์ ์ฝ๋๋ ํ์ผ์ MIME ํ์ ๊ณผ ํ์ฅ์๋ฅผ ๊ฒ์ฌํ์ฌ JPG, PNG ํ์์ ์ด๋ฏธ์ง ํ์ผ๋ง ์ ๋ก๋๋ฅผ ํ์ฉํฉ๋๋ค.
๊ฒฐ๋ก
Node.js์์ Multer๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ผ ์ ๋ก๋ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค. Express ์๋ฒ์ Multer ๋ฏธ๋ค์จ์ด๋ฅผ ํ์ฉํ์ฌ ํด๋ผ์ด์ธํธ๊ฐ ์ ๋ก๋ํ ํ์ผ์ ์๋ฒ์ ์ ์ฅํ๊ณ , ํ์ผ ํฌ๊ธฐ ์ ํ ๋ฐ ํ์ ํํฐ๋ง๊ณผ ๊ฐ์ ์ถ๊ฐ ์ค์ ๋ ๊ฐ๋ฅํฉ๋๋ค. ํ์ผ ์ ๋ก๋๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ฃผ ์ฌ์ฉ๋๋ ๊ธฐ๋ฅ์ด๋ฏ๋ก, ์ด๋ฅผ ์ ํ์ฉํ์ฌ ํจ์จ์ ์ธ ํ์ผ ๊ด๋ฆฌ ์์คํ ์ ๊ตฌ์ถํด๋ณด์ธ์!
๋๊ธ ์ฐ๊ธฐ