아카이브

[Node][Express] Middleware | 03. multer 본문

Backend/Node.js

[Node][Express] Middleware | 03. multer

Rayi 2024. 8. 20. 15:42

패키지 설치가 필요한 미들웨어 입니다.

https://github.com/expressjs/multer/blob/master/doc/README-ko.md

 

multer/doc/README-ko.md at master · expressjs/multer

Node.js middleware for handling `multipart/form-data`. - expressjs/multer

github.com

 

multer는 요청의 ContentType 헤더 값이 multipart/form-data 라면, 요청의 body에 담긴 데이터들을 객체로 불러옵니다.

import express from 'express';
import multer from 'multer';

const app = express();

const upload = multer({ dest: 'uploads/'}) // dest : 서버가 가져온 파일의 목적지를 설정합니다.

// upload.single('attachment') : 'attachment'라는 이름을 가진 한 가지 종류의 데이터만 가져옵니다.
app.post('/files', upload.single('attachment'), (req, res) => {
  console.log(req.file)
  res.json({ message: "upload"})
})

app.listen(3000, () => {
  console.log('Server is listening on port 3000');
});

multipart/form-data의 경우 아래와 같이 요청 형식이 복잡한 편입니다.

때문에 직접 작성하는 일은 드물고, 요청을 자동으로 생성하도록 코드를 구성하는 편입니다.

아래와 같은 경우는 텍스트 형식의 데이터 한 가지만 보내는 요청입니다.

POST http://localhost:3000/files
Content-Type: multipart/form-data; boundary=Boundary01234567890123456789

// 'attachment'라는 이름을 부여한 text/plain 타입의 데이터입니다.
--Boundary01234567890123456789
Content-Disposition: form-data; name="attachment"; filename="hello.txt"
Content-Type: text/plain

Hello!
--Boundary01234567890123456789--

단, 이 때 multer는 dest에 명시된 경로에 생성되는 파일에 무작위 이름을 부여합니다.

이는 서로 다른 클라이언트에서 요청하는 filename이 중복되는 것을 방지하기 위함입니다.

{
  fieldname: 'image',
  originalname: 'profile.txt',
  encoding: '7bit',
  mimetype: 'text/plain',
  destination: 'uploads/',
  filename: '5dd69979f79a83348ef19035d19ddeb4', // 무작위 파일 이름
  path: 'uploads\\5dd69979f79a83348ef19035d19ddeb4',
  size: 22
}

따라서 파일 업로드가 성공적으로 끝난 후 해당 파일을 찾기 위해서는

이후 미들웨어에서 req.file.filename을 통해 접근해야 합니다.

app.post('/files', upload.single('attachment'), (req, res) => {
  // 이후 파일에 접근할 엔드포인트이름을 /resource/파일이름 으로 정했습니다.
  const path = `/resource/${req.file.filename}`
  res.json({ path })
})

이렇게 알아낸 파일이름을 경로로 하여 GET 등으로 접근하면 업로드한 파일을 확인할 수 있습니다.

728x90
Comments