说一说前端文件压缩

基于JSZip的前端文件压缩

1. 简介:

这段时间,项目需要做一个这样的功能:客户端在上传文件的时候(具体文件类型),需要对文件进行压缩再上传以节省带宽和服务器端资源,完成这个功能,我们选择了GitHub上的JSZip,它是一个客户端插件,可以提供客户端压缩功能,作者给出了API,但是实际使用过程中还是有很多问题,下面是实际过程中遇到的各类问题,直至最终完成整个文件压缩再上传至后台。

2.项目相关组件与环境:

前端node.js + webpack 作前后台分离,后端java

3. 具体实现

主要js代码:

var JSZip = require('jszip');
const components = require('components');

$('#confirmBtn').on('click', async function() {
  // 绑定上传的确认按钮,获取到obj等模型文件,并压缩
  let zip = new JSZip();//声明并创建JSZip对象
  var fileBox = $('#fileUploadInput'); //从页面获取到需要上传的文件列表,当然html是一个多文件上传
  var fileList = fileBox[0].files;
  var objName = 'example'; // 这里定义一个压缩文件的名字,以供后台使用,当然也可以动态获取
  //  var flag = false;
  for (const fileObject of fileList) {
    zip = await zipFileAsync(zip, fileObject); //这是设置异步上传,await关键字使得后面的zipFileAsync方法执行结束后才将对象返回给zip变量
  }
  sendFileAsync(zip, objName);
  console.log(zip);
  return false; // 设置return false防止表单提交
});

这部分代码就是异步压缩的核心,以及如何调用的下面的异步压缩算法,上面需要Async与await关键字缺一不可,一开始也尝试过使用同步压缩的方式,但是会出现压缩还没有全部完成,就已经开始提交文件的现象,特别感谢lrh3321的指导,才完整的实现了这个功能。


因为异步压缩的时候我们上传的文件的数量不定,所以上面需要使用await关键字来修饰压缩过程。而下面的压缩过程的实现,最终返回一个promise对象,当压缩过程已完成后,完整的生成的文件存于其中。

/**
 * 异步压缩文件
 * @param zip file
 */
function zipFileAsync(zip, file) {
  const promise = new Promise((resolve) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onloadend = function(e) {
      var result = reader.result;
      //  读完转一下格式
      result = convertBase64UrlToBlob(result);
      console.log(zip);
      console.log(file.name);
      console.log(file.size);
      // resolve 方法保证异步压缩完成后才返回promise
      resolve(
        zip.file(file.name, result, {
          type: 'blob',
        }));
    };
  });
  return promise;
}


这里的demo请查看JSZip给的例子

/**
 * 异步发送文件
 * @param zip file
 */
function sendFileAsync(zip, objName) {
  zip.generateAsync({
    type: 'blob',
    compression: 'DEFLATE', //  force a compression for this file
    compressionOptions: { //  使用压缩等级,1-9级,1级压缩比最低,9级压缩比最高
      level: 6,
    },
  }).then(
      function(content) {
        var formData = new FormData();
        formData.append('Blobfile', content); // 获取上文中压缩的内容,并放入formdata
        formData.append('objName', objName); // 将objName一起放入formdata
        progressBar('Model/UploadModel', formData, content.size); 
      }
  );
  return false;
}
/**
 * 将以base64的图片url数据转换为Blob
 * @param urlData
 * 用url方式表示的base64图片数据
 */
 

http读取图片的时候会已base64编码形式对到服务器,如果不进行重新编码,则无法在图片查看器中查看图片

function convertBase64UrlToBlob(urlData) {
  var bytes = window.atob(urlData.split(',')[1]);
  //  处理异常,将ascii码小于0的转换为大于0
  var ab = new ArrayBuffer(bytes.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i);
  }
  return new Blob([ab], {type: 'image/jpg'});
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值