본문 바로가기
개발/Node JS

Node JS - FormData와 multer로 여러 파일 업로드하기 (Upload Multiple Files with FormData and multer)

by 피로물든딸기 2024. 4. 27.
반응형

Node JS 전체 링크

 

참고

- multer로 이미지 업로드하기

 

다음과 같이 웹에서 여러 파일을 업로드하면 서버로 전송되도록 구현해 보자.


리액트

 

input 태그에 multiple을 설정하면 여러 파일을 선택할 수 있다.

<input type="file" multiple onChange={handleUpload} />

 

handleUpload 구현은 전체 코드를 참고하자.

formData의 append를 이용해 e.target.files를 순회하면서 파일을 추가한다.

한글 파일이 있는 경우 파일 이름을 처리하기 위해 encodeURIComponent를 이용해야 한다.

formDataconfig("content-type": "multipart/form-data")post에 설정하여 서버로 전송하면 된다.

import React from "react";
import axios from "axios";

const FileUpload = () => {
  const handleUpload = async (e) => {
    let files = e.target.files;
    let server = `http://192.168.55.120:3002/file_upload`;

    const formData = new FormData();
    const config = {
      header: { "content-type": "multipart/form-data" },
    };

    for (let file of files) {
      // encodeURIComponent : 한글 파일 처리
      formData.append("files", file, encodeURIComponent(file.name)); 
    }

    const response = await axios.post(server, formData, config);

    console.log(response);
  };

  return (
    <div>
      <input type="file" multiple onChange={handleUpload} />
    </div>
  );
};

export default FileUpload;

Node JS

 

파일 업로드를 처리하기 위해 multer를 설치한다.

npm install multer

 

여기서는 윈도우의 경로에 다운로드 되도록 가정한다.

만약 다운로드 path를 변경하고 싶다면 위의 구현에서 경로를 추가해 req.query.path로 받도록 하면 된다.

let folderPath = "D:\\github\\downloads"; // or req.query.path

 

multerdiskStorage에서 파일이 업로드 될 경로파일의 이름을 설정할 수 있다.

encodeURIComponent인코딩 된 파일을 다시 decodeURIComponent디코딩한다.

  const storage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, folderPath);
    },
    filename: function (req, file, cb) {
      cb(null, decodeURIComponent(file.originalname)); // encodeURIComponent 한글 처리된 디코딩
    },
  });

 

그리고 파일의 개수파일의 크기 제한을 추가하도록 하자.

  const limits = {
    files: 50,
    fileSize: 1024 * 1024 * 1024, // 1G
  };

 

다음 코드로 업로드를 할 수 있다.

  const upload = multer({ storage, limits }).any();

  upload(req, res, (error) => {
    if (error) {
      return res.send({ result: false, error });
    }

    console.log(req.files);

    res.send({ result: true });
  });

 

참고로 현재 구현대로면 파일 이름이 같은 경우, 최신 업로드된 파일로 덮어쓰기가 된다.

 

전체 코드는 다음과 같다.

const express = require("express");
const router = express.Router();
const multer = require("multer");

router.post("/", (req, res) => {
  let folderPath = "D:\\github\\downloads"; // or req.query.path

  const storage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, folderPath);
    },
    filename: function (req, file, cb) {
      cb(null, decodeURIComponent(file.originalname)); // encodeURIComponent 한글 처리된 디코딩
    },
  });

  const limits = {
    files: 50,
    fileSize: 1024 * 1024 * 1024, //1G
  };

  const upload = multer({ storage, limits }).any();

  upload(req, res, (error) => {
    if (error) {
      return res.send({ result: false, error });
    }

    console.log(req.files);

    res.send({ result: true });
  });  
});

module.exports = router;
반응형

댓글