[FDBS] Next.js에서 이미지 파일 다운로드 및 업로드(node.js)

Jay ·2023년 3월 15일
1

Goal

Next.js에서 이미지 파일을 cheerio를 사용해 다운로드 하고, 다운로드 받은 파일을 database에 업로드.

예시코드

let imgUrl = '이미지 URL'

const imgResponse = await fetch(imgUrl);
const imgBuffer = Buffer.from(await imgResponse.arrayBuffer());
const formData = new FormData();
            formData.append("file", new Blob([imgBuffer]), translatedTitle);
const { uploadURL } = await (
              await fetch(`${process.env.URL}/api/files`, {
                method: "GET",
              })
            ).json();

const {
       result: { id },
       } = await (
        			await fetch(uploadURL, { method: "POST", body: formData })
        ).json();

코드 분석

Node.js에서 image Data를 다루기위해선 우선 이미지 데이터를 Buffer 형태로 변환이 필요하다.

따라서 response를 arraybuffer를 거쳐 buffer로 변환.
(필요한 경우 response를 blob으로 우선 변환)

이후 Buffer를 formData에 담아 DB에 업로드한다.

formData key값이 file인 경우 value값으로 blob 혹은 string를 요구하여 new Blob([])을 사용하여 blob으로 변환.

코드 개선

export async function downloadAndUploadImage(
  imgUrl: string,
  translatedTitle: string
) {
  try {
    // Download the image from the URL
    const response = await axios.get(imgUrl, {
      responseType: "arraybuffer",
    });

    // Create a FormData instance
    const formData = new FormData();
    formData.append("file", Buffer.from(response.data), {
      contentType: response.headers["content-type"],
      filename: translatedTitle,
    });

    // Fetch the uploadURL from your API route
    const { uploadURL } = await (
      await fetch(`${process.env.NEXTAUTH_URL}/api/files`, {
        method: "GET",
      })
    ).json();

    // Upload the image to your server using the fetched uploadURL
    const { data } = await axios.post(uploadURL, formData, {
      headers: formData.getHeaders(),
    });

    const {
      result: { id },
    } = data;

    return id;
  } catch (error: any) {
    throw new Error(`Failed to download and upload image: ${error.message}`);
  }
}

response 상세

{
  status: 200,
  statusText: 'OK',
  ...
  req: {
  ~~
  },
  res: IncomingMessage {
  ...
  data: <Buffer ff d8 ff e1 00 18 45 78 69 66 00 00 49 49 2a 00 08 	   00 00 00 00 00 00 00 00 
  00 00 00 ff ec 00 11 44 75 63 6b 79 00 01 00 04 00 00 00 46 00 00     ff e1 03 ... 9605 more bytes>

1. ArrayBuffer?

출처
ArrayBuffer 객체는 이미지, 동영상과 같은 멀티미디어 데이터 덩어리를 표준 자바스크립트(브라우저)에서 다루기 위해 도입되었음.

ArrayBuffer는 자바스크립트에서 원시 데이터(바이너리 데이터)를 직접 다루는 수단으로 사용되며, 이는 메모리를 개발자가 수동으로 관리할 수 있게 해준다.

2. Blob?

BLOB은 Binary Large OBject의 약자로 주로 이미지, 오디오, 비디오와 같은 멀티미디어 파일 바이너리를 객체 형태로 저장한 것을 의미한다.
base64와 달리 string이 아닌 object 이기 때문에 다루기 좀 더 쉽다.

3. Buffer?

클라이언트단에서 ArrayBuffer로 이진 데이터를 다루었다면, 서버단(Node.js)에서는 Buffer 객체로 이진 데이터를 다룬다고 이해하면 된다.

4. Base64?

이진 바이너리 데이터로 메모리에 존재하는 이미지 데이터를 변수에 담아 전송하기 위한 데이터 포맷.(way of encoding binary data (such as images) as ASCII text)
다만 원본 데이터보다 용량이 33% 증가하는 단점이 존재.

etc

const formData = new FormData();
            formData.append("file", new Blob([imgBuffer]), translatedTitle);
profile
Jay입니다.

0개의 댓글