티스토리 뷰

728x90

용량이 많은 파일을 다운로드 받아야 하는데 진행률이 보이면 좋을 것 같아 구현해본다.

그래픽 같은건 angular material이나 bootstrap에 있으니 간편하게 가져와 쓰면 된다.

 

그냥 파일을 다운로드 받으려면

res.download(경로, 다운로드 이름)

이렇게 하면 잘받아 진다.

그런데 진행률을 알려면 어떻게 해야 할까?

서버에서 데이터 다운로드 진행률을 클라이언트가 알아야 하는데

 

생각만으로는 절대 알 수 없으니 구글링!~~

 

router.get('/file/download', async (req, res) => {
    res.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

    res.download(경로, 다운로드 이름);
});

위에 헤더는 브라우저 측에서 접근할 수 있게 해준다

이렇게 서버 사이드는 준비 끝

 

클라이언트는

  onDownload(filename, index) {
    this.service.DOWNLOAD(`/file/download`).subscribe((res: any) => {
      if (res['loaded'] && res['total']) {
	      //백분율 구하기
        this.fileInfos[index].value = Math.round(res['loaded'] / res['total'] * 100);
      }
      if (res['body']) {
        saveAs(res['body'], filename);
      }
    }, err => {
		//err
    });
  }
<button (click)="onDownload('파일명')">download<button>

DOWNLOAD함수는 어떻게 되어있냐면

  DOWNLOAD(dest) {
    return this.http.get(`/file/download`, {
      reportProgress: true,
      observe: 'events',
      responseType: 'blob'
    });
  }

제일 중요한 리스폰스 타입을 blob으로 설정 해주시면 됩니다

 

 

res.body가 true면 saveAs로 저장이 됩니다.

saveAs()는 https://www.npmjs.com/package/file-saver

 

file-saver

An HTML5 saveAs() FileSaver implementation

www.npmjs.com

npm i file-save해주시고

최상단에

import { saveAs } from 'file-saver';

임포트 해주시면 saveAs api를 사용하실 수 있습니다.

 

Math.round(res['loaded'] / res['total'] * 100);

이걸로 1~100까지 숫자가 리턴되니 html에 표시하면 되겠죠 ㅎ

 

 

이슈

pc에서는 대용량 파일도 다운로드가 가능한데

file-saver 사이트에서 보시면 모바일에서는 한계가 있더라구요

그나마 크롬이 2기가 까지 가능한데 네이버 앱이나 삼성 인터넷 브라우저 등은 대용량 파일은 안됩니다.

다 기반은 크로니움?이긴 한데 음....

간단하게 생각해보면 모바일 기기에서 몇 기가파일을 다운 받으면 무제한 쓰시는 분 아니면 위험하겠죠?

특히 외국은 더 심할꺼고

 

결론은 100MB~200MB까지는 다운로드가 가능합니다. 정확한 수치는 홈페이지 참고 또는 구글링 해보세요~

 

그래도 대용량을 다운받아야 한다면 서버사이드에서 그냥 res.downlaod()하시면 됩니다.

 

ps. 저는 단순 코더라~ 경력이 높으신 분들은 대용량도 다운가능하게 할 수 있을거라 봅니다.

728x90
댓글
댓글쓰기 폼