๊ฒ์ํ์ ์ด๋ฏธ์ง ์ ๋ก๋ ๊ธฐ๋ฅ ์ถ๊ฐํ๊ธฐ
multer ๋ชจ๋
multer ๋ชจ๋์ multipart/form-data
๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ node.js ๋ฏธ๋ค์จ์ด์
๋๋ค.
์ด๋ฒ ํฌ์คํ
์์๋ ์ง๋ ํฌ์คํ
์ ์ด์ด์ node.js
์์ ์ด๋ฏธ์ง(ํ์ผ)๋ฅผ ์
๋ก๋ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ํ์ฌ ๊ฒ์ํ ๊ธ์ฐ๊ธฐ ํ๋์๋ ๋ค์๊ณผ ๊ฐ์ด ์ด๋ฏธ์ง ์
๋ก๋ ๊ธฐ๋ฅ์ด ์๋ ์ํ๋ผ์ multer
๋ชจ๋์ ํตํด
๊ฒ์๊ธ๋ง๋ค ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋๋ก ํ๊ฒ ์ต๋๋ค.

ํจํค์ง ์ค์น
$ npm i multer
MySQL ์ปฌ๋ผ ์ถ๊ฐ
๊ธฐ์กด์ ๊ฒ์๊ธ ํ ์ด๋ธ์ ๋ค์๊ณผ ๊ฐ์ ํํ๋ฅผ ๋๊ณ ์์ต๋๋ค.
mysql> desc board;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| idx | int unsigned | NO | PRI | NULL | auto_increment |
| creator_id | varchar(100) | NO | | NULL | |
| title | varchar(100) | NO | | NULL | |
| content | mediumtext | NO | | NULL | |
| passwd | varchar(100) | NO | | NULL | |
| hit | int unsigned | NO | | 0 | |
+------------+--------------+------+-----+---------+----------------+
์ด์ ๊ฐ ๊ฒ์๊ธ๋ง๋ค ์ด๋ฏธ์ง๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ๊ด๋ฆฌํด์ผํ๋ฏ๋ก ์ด๋ฏธ์ง ๊ฒฝ๋ก๋ฅผ ์ ์ฅํ ์ปฌ๋ผ์ ์๋ก ๋ง๋ค์ด์ค๋๋ค.
๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ก DB์ ์ ์ฅํ ๊ฒฝ์ฐ ๋ถํ๊ฐ ํฌ๊ธฐ ๋๋ฌธ์
์ด๋ฏธ์ง ๊ฒฝ๋ก๋ง ์ ์ฅํด๋๊ณ ์๋ฒ์์ ๋ก๋ํด์ ์ ๊ณตํด์ฃผ๋ ํํ๋ก ํ ๊ฒ์
๋๋ค.
mysql> ALTER TABLE board ADD image VARCHAR(200) NOT NULL DEFAULT '';
์ด์ ๋ค์ ๊ฒ์๊ธ ํ ์ด๋ธ์ ํ์ธํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์๋ก์ด ์ปฌ๋ผ์ด ์ถ๊ฐ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
mysql> desc board;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| idx | int unsigned | NO | PRI | NULL | auto_increment |
| creator_id | varchar(100) | NO | | NULL | |
| title | varchar(100) | NO | | NULL | |
| content | mediumtext | NO | | NULL | |
| passwd | varchar(100) | NO | | NULL | |
| hit | int unsigned | NO | | 0 | |
| image | varchar(200) | NO | | | | <== ๐ก
+------------+--------------+------+-----+---------+----------------+
ํ์ผ ์ ๋ก๋ ํผ ์์ฑ
์ด์ ๊ธฐ์กด์ ๊ธ ์์ฑ ํผ์์ ์ด๋ฏธ์ง ์
๋ก๋๋ฅผ ์ํ ํ์ผ ์ ํ ์ฐฝ์ ์๋ก ์ถ๊ฐํด์ค๋๋ค.
form ํ๊ทธ์ ์์ฑ์ผ๋ก enctype="multipart/form-data"
๊ฐ ์ง์ ๋์ด์ผ ํจ์ ์ ์ํฉ๋๋ค.
write.ejs
<form action="/board/write" method="post" enctype="multipart/form-data">
<table border="1">
<!-- ์ค๋ต -->
<tr>
<td>์ด๋ฏธ์ง</td>
<td><input type="file" name="image" /></td>
</tr>
<tr>
<td colspan="2">
<button type="submit">๊ธ์ฐ๊ธฐ</button>
</td>
</tr>
</table>
</form>
router & multer ์ค์
๊ฒ์๊ธ ์ ๋ก๋๋ฅผ ๋ด๋นํ๋ ๋ผ์ฐํธ ํ์ผ์ ๊ฐ์ ๋ช ๊ฐ์ง ์ค์ ์ ํด์ค๋๋ค.
ํ์ผ์ด ์ ์ฅ๋ ๊ฒฝ๋ก๋ ํ์ผ๋ช
์ ๋ณ๊ฒฝํด์ฃผ๊ธฐ ์ํด์๋ multer
๊ฐ์ฒด์ ์ต์
์ ๋ณ๊ฒฝํด์ฃผ๋ฉด ๋ฉ๋๋ค.
์ฌ๊ธฐ์๋ ํ์ฌ ๋ ์ง๋ฅผ ํ์ผ๋ช
์ ์ถ๊ฐํ์ฌ ์ค๋ณต๋ ์ฌ์ง์ด ์์ฑ๋๋ ๊ฒ์ ๋ฐฉ์งํ๋๋ก ํ๊ฒ ์ต๋๋ค.
์ด๋ฏธ์ง ์
๋ก๋๋ฅผ ๋ด๋นํ๋ ๋ผ์ฐํฐ ํ์ผ ์๋จ์ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ํตํด ์ค์ ์ ํด์ค๋๋ค.
express ํ๋ก์ ํธ ์์ฑ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณต๋๋ public/images
๋๋ ํ ๋ฆฌ ํ์์ ์ด๋ฏธ์ง๋ค์ ์ ์ฅํด์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค.
routes/board.js
const multer = require("multer");
const path = require("path");
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public/images/");
},
filename: function (req, file, cb) {
const ext = path.extname(file.originalname);
cb(null, path.basename(file.originalname, ext) + "-" + Date.now() + ext);
},
});
var upload = multer({ storage: storage });
๋ํ ๊ฒ์๊ธ ํ๋์๋ ํ๋์ ์ด๋ฏธ์ง๊ฐ ์กด์ฌํ๋ฏ๋ก upload.single('image')
๋ก
์ด๋ฏธ์ง ์ฒ๋ฆฌ๋ฅผ ์ํ ๋ฏธ๋ค์จ์ด๋ฅผ ์์ฑํฉ๋๋ค.
์ฌ๊ธฐ์ image
๋ input
ํ๊ทธ์ name
์์ฑ๊ฐ์
๋๋ค.
์๊น์ ๋์ผํ๊ฒ board.js
์ ํ์ผ ์
๋ก๋๋ฅผ ๋ด๋นํ๋ ๋ผ์ฐํฐ์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ค์ ํด์ค๋๋ค.
routes/board.js
// ... ์ค๋ต
// ํ์ผ ์
๋ก๋ ๋ผ์ฐํฐ
router.post("/write", upload.single("image"), (req, res, next) => {
const creator_id = req.body.creator_id;
const title = req.body.title;
const content = req.body.content;
const passwd = req.body.passwd;
const image = `/images/${req.file.filename}`; // image ๊ฒฝ๋ก ๋ง๋ค๊ธฐ
const datas = [creator_id, title, content, passwd, image];
const sql =
"INSERT INTO board(creator_id, title, content, passwd, image) values(?, ?, ?, ?, ?)";
connection.query(sql, datas, (err, rows) => {
if (err) {
console.error("err : " + err);
} else {
console.log("rows: " + JSON.stringify(rows));
res.redirect("/board");
}
});
});
์ด๋ฏธ์ง ์ ์ฅ ํ์ธ
์ด์ ํฐ๋ฏธ๋์ ์ด๊ณ ์๋ก์ด ๊ฒ์๊ธ์ ์์ฑํ ๋ค ์ฟผ๋ฆฌ๋ฌธ์ ํตํด ๋ ์ฝ๋๋ฅผ ํ์ธํด๋ณด๋ฉด
๋ค์๊ณผ ๊ฐ์ด ์ด๋ฏธ์ง ๊ฒฝ๋ก๊ฐ ์ ์ฅ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๊ธฐ์กด์ ์ด๋ฏธ์ง๊ฐ ์๋ ๊ฒ์๊ธ๋ค์ ๊ธฐ๋ณธ๊ฐ์ด ์ค์ ๋์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
mysql> select * from board;
+-----+------------+----------------------+---------------------+--------+-----+--------------------------------
| idx | creator_id | title | content | passwd | hit | image |
+-----+------------+----------------------+---------------------+--------+-----+--------------------------------
| 12 | simpson | springfield | ๊ฒ์๊ธ ์์ฑ | 1234 | 0 | |
| 15 | apple | lenna | lenna test | 1234 | 0 | /images/lenna-1589908536559.png |
+-----+------------+----------------------+---------------------+--------+-----+--------------------------------
๋ํ ๋ก์ปฌ ํ๊ฒฝ์ ์ด๋ฏธ์ง๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ ์ฅ๋์๋์ง ํ์ธํด๋ด ์๋ค.
public/images/
ํ์์ ๋ค์๊ณผ ๊ฐ์ด ์ ์ฅ๋ ์๊ฐ๊ณผ ํจ๊ป
์๋ก์ด ํ์ผ๋ช
์ ๋ง๋ ๋ค ์ ์ฅ๋์ด์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.

๊ฒ์๊ธ ์ด๋ฏธ์ง ์ถ๋ ฅ
ํ์ฌ๋ ๊ฒ์๊ธ ์กฐํ ์ ์ ์ฅ๋ ์ด๋ฏธ์ง๋ฅผ ์ถ๋ ฅํ์ง ๋ชปํ๋ ์ํ์ ๋๋ค.

์ด์ ๊ฒ์๊ธ ์กฐํ ์ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ด ์ถ๋ ฅํด์ค ์ ์๋๋ก ๊ธฐ์กด์ ๋ผ์ฐํฐ๋ฅผ ์์ ํ๊ฒ ์ต๋๋ค.
๊ธฐ์กด ์ฟผ๋ฆฌ๋ฌธ์ ์์ฒญ ํ๋์ image
๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
routes/board.js
router.get("/read/:idx", (req, res, next) => {
const idx = req.params.idx;
const sql =
"SELECT idx, creator_id, title, content, hit, image FROM board WHERE idx=?";
connection.query(sql, [idx], (err, row) => {
if (err) {
console.error(err);
} else {
res.render("read", { title: "๊ธ ์กฐํ", row: row[0] });
}
});
});
๊ทธ๋ฆฌ๊ณ ejs ํ์ผ์์ img
ํ๊ทธ๋ฅผ ํตํด ์ ์ ํ์ผ์ ํ๋ฉด์ ์ถ๋ ฅํ๋๋ก ํฉ๋๋ค.
์ด๋ ์ด๋ฏธ์ง ์์ค๋ ์๋ฒ๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ row
๊ฐ์ฒด์์ ๊ฐ์ ธ์ค๋๋ก ํฉ๋๋ค.
read.ejs
<table>
<!-- ์ค๋ต -->
<tr>
<td>์ด๋ฏธ์ง</td>
<td><img src="<%= row.image %> " alt="์ด๋ฏธ์ง" width="300" /></td>
</tr>
</table>
๊ฒฐ๊ณผ ํ์ธ

์ฐธ๊ณ ์๋ฃ
'๐จโ๐ป web.dev > node' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
TypeDI ๋ฅผ ํ์ฉํ ์์กด์ฑ ์ฃผ์ (0) | 2022.05.28 |
---|---|
Node.js ์๋ฒ์ Redis ์ ์ฉํ๊ธฐ (1) | 2022.05.28 |
Node.js์ MySQL๋ฅผ ์ด์ฉํ ๊ฒ์๊ธ ์์ฑํ๊ธฐ ํํ ๋ฆฌ์ผ (0) | 2021.03.05 |
Sequelize ORM์์ migration ํ์ฉํ๊ธฐ (0) | 2021.03.03 |
Node.js ํ๊ฒฝ์์ ๋ค์ด๋ฒ Open API ํ์ฉํ๊ธฐ (0) | 2021.03.02 |
๐ฌ ๋๊ธ