노드 서버용 메모리 내 파일 생성

12822 단어 tutorialtypescriptnode

사용 사례


  • 파일을 반환하는 끝점을 작성해야 합니다(예: .zip/.pdf).
  • 어떤 이유로 서버에 파일을 저장할 수 없습니다*

  • 해결책



    일반적인 생각


  • 파일을 바이너리 스트림으로 생성
  • 기억에 담다
  • API를 통해 스트림을 파이프합니다.



  • QR 코드가 포함된 PDF 생성



  • PDF 및 QR 코드 라이브러리 설치

    
      npm i qrcode && npm i --save-dev @types/qrcode
      npm i pdf-lib
    
    


  • 데이터 URI로 QR 코드 생성

    
      export const generateDataUri = (content: string): Promise<string> => {
        return QRCode.toDataURL(content);
      };
    
    


  • PNG로 QR 코드 생성 및 포함

    
      const pdfDoc = await PDFDocument.create();
      const page = pdfDoc.addPage();
    
      const qrCodeDataUri = await generateDataUri(name);
      const pngImage = await pdfDoc.embedPng(qrCodeDataUri);
      page.drawImage(pngImage, {
        x: page.getWidth() / 2 - pngImage.width / 2,
        y: (page.getHeight() - pngImage.height) / 2,
        width: pngImage.width,
        height: pngImage.height,
      });
    
    


  • PDF를 버퍼로 반환

    
      const pdfBytes = await pdfDoc.save();
    
      return {
        contentBytes: Buffer.from(pdfBytes),
        filename
      };
    
    


  • 응답을 파일로 구성

    
      const respondWithAttachingFile = (
        contentBytes: Buffer,
        res: Response,
        filename: string,
        filetype: string
      ): void => {
        res.setHeader("Content-Type", `application/${filetype}`);
        res.setHeader("Content-Disposition", `attachment; filename=${filename}`);
    
        res.status(200).end(contentBytes);
      };
    
      respondWithAttachingFile(contentBytes, res, filename, "pdf");
    
    


  • 여러 PDF의 아카이브 생성



  • 아카이브 및 스트림 버퍼 라이브러리 설치

    
      npm i archiver && npm i --save-dev @types/archiver
      npm i stream-buffer && npm i --save-dev @types/stream-buffer
    
    

  • PDF 지침에 따라 파일 생성

  • 파일 버퍼를 아카이브 파일로 파이프

    
      export const archiveFiles =
        async (fileBuffers: FileBuffer[], outputFilename: string): Promise<FileBuffer> => {
          const archive = archiver("zip", {
            zlib: { level: 9 },
          });
          const filename =
            `${outputFilename}.zip`
              .replace(/ /g, "");
    
          const outputStreamBuffer = new streamBuffers.WritableStreamBuffer({
            initialSize: (1000 * 1024),
            incrementAmount: (1000 * 1024)
          });
    
          archive.pipe(outputStreamBuffer);
    
          fileBuffers.forEach(fileBuffer =>
            archive.append(Buffer.from(fileBuffer.contentBytes), { name: fileBuffer.filename }));
    
          await archive.finalize();
          outputStreamBuffer.end();
    
          return new Promise((resolve, reject) => {
            const contentBytes = outputStreamBuffer.getContents();
            if (contentBytes !== false) {
              resolve({ filename, contentBytes });
            }
            reject(new Error("Buffering failed."));
          });
        };
    
    


  • 응답을 파일로 구성

    
      respondWithAttachingFile(contentBytes, res, filename, "zip");
    
    


  • 전체 솔루션을 찾을 수 있습니다. https://github.com/angiesasmita/generate-file-in-memory

    파일을 저장할 수 없는 몇 가지 이유(중간 단계로)


  • 보안 - 생성된 파일은 민감하며 전혀 저장할 수 없습니다
  • .
  • 쓰기 액세스 권한 없음(가장 일반적인 문제)
  • 정리 정책(가능성 없음) - 서버에 준수해야 하는 특정 정리 정책이 있으며 구성에 추가 노력이 필요함

  • 고려 사항


  • 동시 요청(max_number_of_concurrent_requests x max_size_of_file < server_memory) 발생 시 서버에 임시로 여러 파일 스트림을 보유할 수 있는 충분한 메모리가 있는지 확인하십시오.
  • 좋은 웹페이지 즐겨찾기