[Node.js] 파일 업로드를 위한 formData 만들기

도도·2021년 10월 4일
0

기술Velog

목록 보기
27/28

파일 업로드를 위한 formData 만들기

전제사항

시나리오

  1. 로고 파일들을 몇백개를 수집을 마친 상황에서 파일을 읽어서 uploader API에 보내야 한다.
  2. 이를 위해 Node.js 의 파일시스템으로 재귀적으로 파일만 탐색하고
  3. uploader API에 formdata를 전송해 보자.

재귀적으로 파일 탐색하기 코드

알고리즘

  • path를 읽어서 파일 목록을 불러온다.
  • 파일이라면 원하는 비즈니스 로직을 수행, 아니라면 재귀적으로 탐색
// example - 디렉터리 순회하기 + 파일읽기

// readdir 의 {withFileTypes: true} 옵션을 주어 fs.Dirent[]객체를 반환 하도록 함
// 객체 안에는 isDirectory 함수가 있음

const fs = require('fs');
const util = require('util');
const path = require('path');

const readdir = util.promisify(fs.readdir);

const main = async () => {
  const recursiveReadFile = async (fileName) => {
    // 파일들 불러오기
    let files = await readdir(path.join(__dirname, fileName), {
      withFileTypes: true,
    });

    // 파일들 순회
    files.forEach(async (file) => {
      // console.log(`file.isDirectory ${file.isDirectory()} file.name ${file.name}`);
      console.log(
        `[${file.isDirectory() ? 'Dir' : 'File'}] ${fileName}/${file.name}`,
      );
      // 디렉터리인 경우
      if (file.isDirectory()) {
        // console.log("directory 추가 검색");
        await recursiveReadFile(fileName + '/' + file.name);
      }
    });
  };
  await recursiveReadFile('a');
};
main();

재귀적으로 파일을 탐색하여, 파일이면 파일을 읽어 formData로 전송하기

알고리즘

  • path를 읽어서 파일 목록을 불러온다.
  • 파일이라면 원하는 비즈니스 로직을 수행, 아니라면 재귀적으로 탐색

비즈니스 로직

  • form-data 모듈을 설치하여, formData 객체를 만들고
  • createReadStream 으로 파일을 버퍼로 읽어 들인 다음
  • formData에 넣고, header를 Axios에 첨부하여 보낸다.
// example - 디렉터리 순회하기 + 파일읽어서 + formData로 전송 -> S3 업로드 하기

// readdir 의 {withFileTypes: true} 옵션을 주어 fs.Dirent[]객체를 반환 하도록 함
// 객체 안에는 isDirectory 함수가 있음

const fs = require('fs');
const util = require('util');
const path = require('path');
const FormData = require('form-data');
const Axios = require('axios').default;
const readdir = util.promisify(fs.readdir);

const main = async () => {
  const fileUpload = async (fileName) => {
    try {
      const formData = new FormData();
      formData.append(
        'file',
        fs.createReadStream(path.join(__dirname, fileName)),
      );
      const url = 'http://127.0.0.1:4000/v1/api/upload/ticker';
      const res = await Axios({
        method: 'post',
        url,
        data: formData,
        headers: {
          ...formData.getHeaders(),
          'x-jwt':
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbF9pZCI6InlwZDAzMDA4QGdtYWlsLmNvbSIsImlhdCI6MTYyOTc3NTQ0N30.BHqv4vuTGo8ZHjDJxHreGmJ_X2HHrjmLJB3o5Zk_aIQ',
        },
      });
      // console.log("res", res.status, res.data);
      if (res.status === 201) {
        console.log('✔ ok', fileName);
      }
    } catch (error) {
      // console.log(error);
    }
  };
  // await fileUpload("logo/000020.jpg");

  const recursiveReadFile = async (fileName) => {
    // 파일들 불러오기
    let files = await readdir(path.join(__dirname, fileName), {
      withFileTypes: true,
    });

    // 파일들 순회
    files.forEach(async (file) => {
      // console.log(`file.isDirectory ${file.isDirectory()} file.name ${file.name}`);
      console.log(
        `[${file.isDirectory() ? 'Dir' : 'File'}] ${fileName}/${file.name}`,
      );
      await fileUpload(`${fileName}/${file.name}`);
      // 디렉터리인 경우
      if (file.isDirectory()) {
        // console.log("directory 추가 검색");
        await recursiveReadFile(fileName + '/' + file.name);
      }
    });
  };
  await recursiveReadFile('logo');
};
main();
profile
프론트 주력의 JS 개발자 입니다.! Node.js, React, NestJS 에 관심이 많습니다.

0개의 댓글