😎 κ³΅λΆ€ν•˜λŠ” μ§•μ§•μ•ŒνŒŒμΉ΄λŠ” μ²˜μŒμ΄μ§€?

[Express μ›Ή μ„œλ²„ λ§Œλ“€κΈ°] (2) 미듀웨어 μ’…λ₯˜ & multer μ‚¬μš©ν•˜κΈ° λ³Έλ¬Έ

πŸ‘©‍πŸ’» λ°±μ—”λ“œ(Back-End)/Node js

[Express μ›Ή μ„œλ²„ λ§Œλ“€κΈ°] (2) 미듀웨어 μ’…λ₯˜ & multer μ‚¬μš©ν•˜κΈ°

μ§•μ§•μ•ŒνŒŒμΉ΄ 2023. 4. 27. 00:14
728x90
λ°˜μ‘ν˜•

<λ³Έ λΈ”λ‘œκ·ΈλŠ” Node.js κ΅κ³Όμ„œλ₯Ό μ°Έκ³ ν•΄μ„œ κ³΅λΆ€ν•˜λ©° μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€ :-)>

 

πŸŽ€ λ‹€μ–‘ν•œ 미듀웨어

🌈 dotenv

: .env νŒŒμΌμ„ μ½μ–΄μ„œ process.env둜 λ§Œλ“ λ‹€

 

🌈 morgan

: 둜그 좜λ ₯

ex) combined, common, short, tiny

// dev
[HTTP λ©”μ„œλ“œ] [μ£Όμ†Œ] [HTTP μƒνƒœ μ½”λ“œ] [응닡 속도]-[응닡 λ°”μ΄νŠΈ]

 

🌈 static

: 정적인 νŒŒμΌλ“€μ„ μ œκ³΅ν•˜λŠ” λΌμš°ν„° μ—­ν• 

: ν•¨μˆ˜μ˜ 인수둜 정적 νŒŒμΌλ“€μ΄ 담겨 μžˆλŠ” 폴더λ₯Ό μ§€μ •ν•œλ‹€

 

🌈 body-parser

: μš”μ²­μ˜ 본문에 μžˆλŠ” 데이터λ₯Ό ν•΄μ„ν•΄μ„œ req.body 객체둜 λ§Œλ“€μ–΄μ£ΌλŠ” 미듀웨어

: 폼 λ°μ΄ν„°λ‚˜ AJAX 데이터 처리

// μš”μ²­μ˜ 본문이 버퍼 데이터 일 λ•Œ
app.use(bodyParser.raw());

// ν…μŠ€νŠΈ 데이터일 λ•Œ 해석
app.use(bodyParser.text());

// false : λ…Έλ“œμ˜ querystring λͺ¨λ“ˆμ„ μ‚¬μš©ν•˜μ—¬ μΏΌλ¦¬μŠ€νŠΈλ§μ„ 해석
// true : λ…Έλ“œμ˜ qs λͺ¨λ“ˆμ„ μ‚¬μš©ν•˜μ—¬ μΏΌλ¦¬μŠ€νŠΈλ§μ„ 해석
{ extended: false }

 

🌈 cookie-parser

: μš”μ²­μ— λ™λ΄‰λœ μΏ ν‚€λ₯Ό 해석해 req.cookies 객체둜 λ§Œλ“ λ‹€

res.cookie(ν‚€, κ°’, μ˜΅μ…˜)

 

🌈 express-session

: μ„Έμ…˜ κ΄€λ¦¬μš© 미듀웨어

: μ„Έμ…˜μ„ κ΅¬ν˜„ν•˜κ±°λ‚˜ νŠΉμ • μ‚¬μš©μžλ₯Ό μœ„ν•œ 데이터λ₯Ό μž„μ‹œμ μœΌλ‘œ μ €μž₯ν•΄λ‘˜ λ•Œ 맀우 유용

app.use(session({
  // μš”μ²­μ΄ 올 λ•Œ μ„Έμ…˜μ— μˆ˜μ • 사항이 생기지 μ•Šλ”λΌλ„ λ‹€μ‹œ μ €μž₯할지 μ„€μ •
  resave: false,
  // μ„Έμ…˜μ— μ €μž₯ν•  내역이 없더라도 μ²˜μŒλΆ€ν„° μ„Έμ…˜μ„ 생성할지 μ„€μ •
  saveUninitialized: false,
  // μΏ ν‚€λ₯Ό μ„œλͺ…ν•˜λŠ”λ° secret κ°’ ν•„μš”
  secret: process.env.COOKIE_SECRET,
  // tptus znzldp eogks tjfwjd
  cookie: {
    // ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μΏ ν‚€ 확인 λͺ»ν•¨
    httpOnly: true,
    // https κ°€ μ•„λ‹Œ ν™˜κ²½μ—μ„œλ„ μ‚¬μš© κ°€λŠ₯
    secure: false,
    // => λ°°ν¬μ‹œ https 적용 true 섀정이 μ’‹μŒ
  },
  name: "session-cookie",
}));

 

🌈 multer

: 이미지, λ™μ˜μƒ 등을 λΉ„λ‘―ν•œ μ—¬λŸ¬ 가지 νŒŒμΌλ“€μ„ λ©€ν‹°νŒŒνŠΈ ν˜•μ‹μœΌλ‘œ μ—…λ‘œλ“œν•  λ•Œ μ‚¬μš©ν•˜λŠ” 미듀웨어

: λ©€ν‹°νŒŒνŠΈλž€ enctype이 multipart/form-data 폼을 톡해 μ—…λ‘œλ“œν•˜λŠ” λ°μ΄ν„°μ˜ ν˜•μ‹ 

 

πŸŽ€ multer 둜 이미지 μ—…λ‘œλ“œν•˜κΈ°

🌈 app.js

// express : http λͺ¨λ“ˆ λ‚΄μž₯λ˜μ–΄μ„œ μ„œλ²„μ˜ μ—­ν• 
const express = require("express");
const app = express();
// process.env 관리
const dotenv = require("dotenv");
// 미듀웨어
const cookieParser = require("cookie-parser");
const session = require("express-session");
const morgan = require("morgan");
const multer = require("multer");
const fs = require("fs");
// 파일 경둜
const path = require("path");
const { fstat } = require("fs");
require("dotenv").config();

dotenv.config();
// μ„œλ²„κ°€ 싀행될 포트
// app.set("ν‚€, κ°’") : 데이터 μ €μž₯
app.set("port", process.env.PORT || 8000);

// dev : [HTTP λ©”μ„œλ“œ][μ£Όμ†Œ][HTTP μƒνƒœ μ½”λ“œ][응닡 μ½”λ“œ]-[응닡 λ°”μ΄νŠΈ]
app.use(morgan("dev"));
app.use("/", express.static(path.join(__dirname, "public")));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(session({
  // μš”μ²­μ΄ 올 λ•Œ μ„Έμ…˜μ— μˆ˜μ • 사항이 생기지 μ•Šλ”λΌλ„ λ‹€μ‹œ μ €μž₯할지 μ„€μ •
  resave: false,
  // μ„Έμ…˜μ— μ €μž₯ν•  내역이 없더라도 μ²˜μŒλΆ€ν„° μ„Έμ…˜μ„ 생성할지 μ„€μ •
  saveUninitialized: false,
  // μΏ ν‚€λ₯Ό μ„œλͺ…ν•˜λŠ”λ° secret κ°’ ν•„μš”
  secret: process.env.COOKIE_SECRET,
  // tptus znzldp eogks tjfwjd
  cookie: {
    // ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μΏ ν‚€ 확인 λͺ»ν•¨
    httpOnly: true,
    // https κ°€ μ•„λ‹Œ ν™˜κ²½μ—μ„œλ„ μ‚¬μš© κ°€λŠ₯
    secure: false,
    // => λ°°ν¬μ‹œ https 적용 true 섀정이 μ’‹μŒ
  },
  name: "session-cookie",
}));

// multer
try {
  fs.readdirSync("uplads");
} catch (error) {
  console.error("uploads 폴더가 μ—†μ–΄ uploads 폴더 생성함");
  fs.mkdirSync("uploads");
}

const upload = multer({
  // 어디에(destination) μ–΄λ–€ 이름(filename)으둜 μ €μž₯할지
  storage: multer.diskStorage({
    destination(req, file, done) {
      done(null, "uploads/");
    },
    filename(req, file, done) {
      const ext = path.extname(file.originalname);
      // 파일λͺ…+ν˜„μž¬μ‹œκ°„.ν™•μž₯자 파일λͺ…μœΌλ‘œ μ—…λ‘œλ“œ
      done(null, path.basename(file.originalname, ext) + Date.now() + ext);
    },
  }),
  // μ—…λ‘œλ“œμ— λŒ€ν•œ μ œν•œ 사항
  // 파일 μ‚¬μ΄μ¦ˆ(fileSize, λ°”μ΄νŠΈ λ‹¨μœ„)
  limits: { fileSize: 5 * 1024 * 1024 },
});

// 미듀웨어 : μš”μ²­κ³Ό 응닡을 μ‘°μ •
// μš”μ²­, 응닡, λ‹€μŒ λ―Έλ“€μ›¨μ–΄λ‘œ λ„˜μ–΄κ°€κΈ°
app.get("/upload", (req, res) => {
  res.sendFile(path.join(__dirname, "multipart.html"));
});

app.post("/upload",
  upload.fields([{ name: "image1" }, { name: "image2" }]),
  (req, res) => {
    console.log(req.filies, req.body);
    res.send("ok");
  },);
app.use((req, res, next) => {
  console.log("λͺ¨λ“  μš”μ²­μ— λ‹€ 싀행됨");
  next();
});

app.get("/", (req, res, next) => {
  console.log("GET / μš”μ²­μ—μ„œλ§Œ μ‹€ν–‰");
  next();
}, (req, res) => {
  throw new Error("μ—λŸ¬λŠ” μ—λŸ¬ 처리 λ―Έλ“€μ›¨μ–΄λ‘œ κ°„λ‹€");
});

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send(err.message);
});

// HTTP μ›Ή μ„œλ²„μ™€ 동일
app.listen(app.get("port"), () => {
  console.log(app.get("port"), "빈 ν¬νŠΈμ—μ„œ λŒ€κΈ°μ€‘");
});

 

🌈 multipart.html

<form action="/upload" method="post" enctype="multipart/form">
    <input type="file" name="image1" />
    <input type="file" name="image2" />
    <input type="text" name="title" />
    <button type="submit">μ—…λ‘œλ“œ</button>
</form>

 

 

728x90
λ°˜μ‘ν˜•
Comments