send ZIP file from back to front

azi_zero·2021년 7월 1일
0

leave a mark 🐾

목록 보기
1/6
post-thumbnail

📨 backend에서 만든 zip파일 front로 보내기 📨

저처럼 고통받는 중생이 없기를 바라며.. 🤦‍♀️

💡 사용 목적

string 형태의 csv 파일을 하나의 zip 파일로 압축

🌿 개발 환경_1

back = Express.js
front = React.js

🌞 사용한 library

express-zip

🎀 code

// backend
const zip = require('express-zip')

let zip_file = [];
zip_file.push({
  path: `${local_file_path}`,
  name: `${file_name}`
});
...
res.zip(zip_file, `${zip_file_name}`,);
// frontend
import {saveAs} from 'file-saver';

const {data} = await axios.post(...,{responseType:'blob'});
const blob = new Blob([data], {type: 'application/zip'});
saveAs(blob, filename);

🌿 개발 환경_2

back = 웹 프레임워크 koa를 사용 (in strapi)
front = react.js 사용

🌞 사용한 library

adm-zip

🎀 code

// backend
const Admzip = require('adm-zip');

const zip = new AdmZip(); //create archives
...
zip.addFile(FILENAME, Buffer.from(STRINGDATA, 'utf-8')); //add file directly
const bufferResult = zip.toBuffer(); 

ctx.send(bufferResult);
// frontend
import {saveAs} from 'file-saver';

const {data} = await axios.post(...,{responseType:'arraybuffer'});
const blob = new Blob([data], {type: 'application/zip'});
saveAs(blob, filename);

🧱 삽질 이유 (제일 중요)

가장 근본적인 원인은 express.js기반의 백엔드 코드를 koa 웹 프레임워크로 옮기면서 발생!
삽질의 세부적인 원인을 살펴보면...

  1. koa를 사용하기 때문에 express-zip을 쓸 수 없음
  2. express-zip 라이브러리가 관리가 안된지 워낙 오래됨
  3. JSZip라이브러리는 이 플랫폼(koa?)에서 blob을 지원안해줌
  4. blob을 쓰고 싶음( 💩 똥고집 💩 )
  5. csv파일을 로컬에 저장해서 불러오기보다 csv가 생성되면 바로 zip에 넣어주고 싶었음

하나씩 되짚어보며 앞으로 같은 실수를 하지 않도록! ( 지금부터는 혼잣말 )

🚧 🚧 🚧 🚧 🚧 🚧 🚧 🚧
1~2 short
express-zip은 사실 너무 편했다...
csv파일 생성하고 같은 array에 넣어주고 res.zip으로 보내주기만 하면되니까...
그런데 너무 관리가 오랫동안 안된 라이브러리이기도 했고,
애초에 기반 프레임워크가 달라졌으니 바꿀 수 밖에 없었다!

🚧 🚧 🚧 🚧 🚧 🚧 🚧 🚧
3~4 long
가장 먼저, JSZip에 매달린 이유는 다운로드수가 가장많았고... (대세를 따르는게 안전하다는 생각에..?)
예시코드를 보고 프론트단에서 아무 파일이나 생성해서 실행해보니 zip파일이 잘 만들어지더라..

// in backend
zip.generateAsync({type:"blob"}).then(function(content) {
    ctx.send(content)
});

이 코드를 적으니 돌아오는 👺 에러놈..
blob is not supported by this platform
해당 에러 내용에 대해 열심히 구글링해보니 여기저기에서 이 플랫폼에서 blob을 쓸 수 있게 해주는 코드를 공유하고 있는 상황 발견.. 여기서부터 💩 고집 시작 (젭알 멈춰...plz..)
🐤 : '그래! 쓸 수 있게 해주는 코드가 몇개 보이니까 나도 쓸 수 있게 잘 써먹어보자!'

🐤 : blob.. binary large object.. 나 사실 얘가 type이라는 것만 알지 아무것도 모르는데 내가 얘 쓰고싶다고 얘가 여기에서 잘 쓰여줄까..?
그러다 확인사살의 순간에 JSZip은 저희와 함께할 수 없게되었습니다

console.log(JSZip.support);
//출력문
{
  base64: true,
  array: true,
  string: true,
  arraybuffer: true,
  nodebuffer: true,
  uint8array: true,
  👀 blob: false,👀
  nodestream: true
}

보고싶지도.. 믿고싶지도 않았는데 수많은 true들 사이에서 슬프도록 빛나는 false놈...

🐤 : '여기서 지면 나는 평생 zip의 패배자다라는 마인드로 바로 회선변경'

adm-zip설치
역시 1등보단 2등이 인간미 넘치고 괜히 정감가고 친해지고싶고 그런걸까..
예시코드를 봤는데 너무너무 쉬워보이잖아!!!

var zip = new AdmZip();
	
// add file directly
var content = "inner content of the file";
zip.addFile("test.txt", Buffer.alloc(content.length, content), "entry comment goes here");

// get everything as a buffer
var willSendthis = zip.toBuffer();

🚧 🚧 🚧 🚧 🚧 🚧 🚧 🚧
5 short

원래 express 환경에서 작성한 csv 다운로드 코드는
하나의 csv파일 안에 들어갈 데이터를 다 갖추면 파일을 생성해서 local에 저장하고,
local에 저장한 파일들을 압축하는 방식이었는데,
strapi 특성상 파일이 바뀌면 매번 서버가 재시작되기 때문에 아주 곤란쓰하고 머리가 아팠다..

처음에는 ✨ .tmp 폴더에 넣고 gitignore을 통해서 인식하지않게 ✨ 할 수 있었는데
그렇게되면 git에 push하고 다른 개발자가 쓸 때에는 .tmp를 만들어줘야하는
사실 그렇게 귀찮지는 않지만 뭔가 거슬리는 지점이 있었기에..!
string형태로 저장해서 파일 생성없이 바로 zip파일에 파일형태로 저장되는 것이 필요했다!

zip.addFile("test.txt", Buffer.alloc(content.length, content), "entry comment goes here");

이 아름다운 코드 한 줄...
나의 모든 needs를 해결해주는 🔅 빛 🔅 그리고 🔅 빛 🔅 그저 🔅 빛 🔅

사실 api 문서는 엄청 읽기 싫게 생겨서 크게 맘에 들지는 않았는데
긴가민가하며 코드를 적어보았더니!!!!!

원하는 zip파일에 원하는 파일들이 쏙쏙 예쁘게 들어가서 아주 예쁜 파일이 다운받아졌다!!!!!!!!!

🧐 더 알아봐야 할 부분

  • XMLHttpRequest.responseType 공부하기
  • blob, arraybuffer 공부하기 (arraybuffer쓴 이유.. 그냥 buffer들어있길래..)

👊 remind

  • api 읽기 싫게 생겼다고 대충 읽지 말자
  • 너무 삽질해서 지칠때는 일단 지금은 하지말자
    6시간동안 zip에 시달리고 꼴도보기 싫어서 바로 접고 다음날 다시 시작했더니 성공!
    🙈 꼴보기 싫을 땐 꼴보지 말아야 하는 법칙 🙈 이번에도 증명 성공
profile
잘 하고 싶은 욕심을 가득 갖고 태어남

0개의 댓글