TIL

240514_TIL : 파일 다운로드 구현

hyriver(강화영) 2024. 5. 15. 19:41

api 요청으로 받은 데이터를 다운로드 하기 위해서는 arraybuffer를 blob으로 변환시키고, 다운로드 링크의 클릭이벤트를 자동으로 실행하여 구현한다.

 

const { mutate } = useMutation(
  () =>
    request({
      url: "/download",
      method: "post",
      data: { row, column },
      responseType: "arraybuffer",
    }),
  {
    onSuccess: (data) => {
      // 1. 받은 데이터 ArrayBuffer를 Blob으로 변환
      const blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });

      // 2. Blob을 참조하는 URL 생성
      const url = window.URL.createObjectURL(blob);

      // 3. 다운로드를 위한 링크 요소 생성 및 설정
      const link = document.createElement("a");
      link.href = url;
      link.setAttribute("download", "file.xlsx"); // 파일 이름 설정

      // 4. 링크를 문서 body에 추가
      document.body.appendChild(link);

      // 5. 클릭 이벤트가 따로 클릭하지 않아도 바로 실행되도록 트리거됨
      link.click();

      // 6. 링크요소를 body에서 제거
      document.body.removeChild(link);

      // 7. 사용이 끝난 url 객체 해제
      window.URL.revokeObjectURL(url);
    },
  }
);

 

 

1. arrayBuffer를 blob으로 전환

Blob 객체는 이진법 데이터(이미지, 비디오, 엑셀 파일 등)를 브라우저에서 다룰 수 있도록 하는 객체이다.

그리고 여기서 지정한 타입은 MIME 타입(인터넷에서의 파일 형식)을 설정하는 것인데

"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 이것은 .xlsx 형식을 뜻한다.

 

.xlsx 파일 mime type

엑셀파일 다운로드 처리시 .xls 파일의 mime type 은 application/vnd.ms-excel 입니다. 그러나 .xlsx 파일을 application/vnd.ms-excel 로 지정하면 firefox 등에서는 부분적으로 문제가 생기는군요. .xlsx 파일의 경우

fronteer.kr

그외 mine타입은 여기서 볼 수 있다

 

 

2. blob을 참조하는 url 생성

임시 url을 생성하여 blob이라는 데이터를 직접 브라우저에서 접근할 수 있도록 하는 작업이다.

URL.createObjectUrl()은 URL을 DOMString으로 변환하는 기능을 한다. 해당 url은 window창이 사라지면 함께 사라지고 다른 window에서는 재사용이 불가능하며 url의 수명이 한정되어있다.

 

👉 그래서 나중에 사용이 끝난 url은 메모리 누수를 위해 삭제시켜줌!

URL.createObjectUrl()를 사용해서 img를 업로드하여 띄우는 것을 구현하기도 한다. (아래참조)

 

createObjectURL을 사용해서 이미지 업로드 후 미리보기

대부분의 서비스에서는 이미지 업로드 시, 내가 올린 사진이 어떤 사진인지 미리 확인할 수 있는 "미리보기" 단계를 거친 후에 이미지를 업로드 하는 기능을 제공하고 있다.

velog.io

 

 

3. 다운로드를 위한 링크요소<a> 생성 및 설정

<a>요소를 생성하여 위에서 만든 url을 할당하여 이 링크를 클릭하면 데이터를 다운로드 할 수 있도록 한다.

setAttribute 메서드는 지정된 요소의 속성값을 설정한다.

// bgcolorRed라는 css 클래스 명이 있을 때
button.setAttribute("class", "bgcolorRed");

 

마찬가지로 setAttribute 메서드를 사용하여 다운로드 속성에서 파일명을 지정할 수 있다.

 

 

4. 링크를 문서 body에 추가

appendChild() 메소드는 지정된 요소를 부모의 자식으로 추가한다.

위에서 생성한 링크요소인 link를 document.body에 추가, 즉 DOM에 추가하여 a 태그의 클릭이벤트를 가능하게 하기 위함이다.

 

 

5. 클릭 이벤트가 따로 클릭하지 않아도 바로 실행되도록(트리거되도록)

클릭이벤트로 a태그의 href 속성에 설정된 Blob URL에서 파일을 다운로드 하도록 한다.

 

 

6. 링크를 문서 body에 제거

링크의 클릭이벤트 이후에 이 요소는 HTML에서 필요하지 않으므로 body에서 제거한다.

이렇게 불필요한 요소를 삭제하여 성능을 최적화시키고, 리소스를 효율적으로 관리할 수 있다.

 

 

7. 사용이 끝난 url객체 해제

createObjectURL에 의해 생성된 URL은 사용 후 명시적으로 해제시켜야 한다.

이렇게 하면 브라우저가 URL에 대해 할당한 메모리 리소스를 회수하여 메모리 누수를 방지한다.

'TIL' 카테고리의 다른 글

240705_TIL  (1) 2024.07.15
240520_TIL : chakra ui의 useCheckboxGroup  (0) 2024.05.21
240507_TIL  (2) 2024.05.08
240426_TIL  (0) 2024.04.26
231231_TIL : react-native 시작하기  (0) 2023.12.31