切片上传

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>upload</title>
  <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
</head>

<body>
  <input type="file" name="file" id="file">
  <button id="upload">上传</button>
  <script type="text/javascript">
    var bytesPerPiece = 1024 * 1024; // 每个文件切片大小定为1MB .
    var totalPieces;   //切片总数
    //发送请求
    $("#upload").click(upload)
    function upload() {

      var blob = document.getElementById("file").files[0];
      // 文件唯一标识符号,防止多个用户一起上传文件时切片混乱
      var uuidfolder = uuid(8, 16);
      // 开始切割的位置
      var start = 0;
      // 切割的结束位置
      var end;
      // 切片的索引
      var index = 0;
      // 回调计数器
      var count = 0;
      // 文件的大小
      var filesize = blob.size;
      // 文件的名称
      var filename = blob.name;
      //计算文件切片总数
      totalPieces = Math.ceil(filesize / bytesPerPiece);
      // 启动while循环对文件切片
      while (start < filesize) {
        // 设置切片的结束位置
        end = start + bytesPerPiece;
        // 对最后一片数据进行处理(可以省略)
        if (end > filesize) {
          end = filesize;
        }
        // 切割文件
        var chunk = blob.slice(start, end);//切割文件
        console.log(chunk)
        // 给每一片切片设置名字,名字的值为原始名称加索引,这样做是为了让后端可以按照索引顺序合并图片。
        var sliceIndex = blob.name + index;
        // 利用formData来传递数据
        var formData = new FormData();
        formData.append("file", chunk, sliceIndex);
        formData.append("uuidfolder", uuidfolder);
        formData.append("imgorder", index);
        $.ajax({
          url: '/upload3',
          type: 'POST',
          data: formData,
          processData: false,  // 不处理数据
          contentType: false,  // 不设置内容类型
        }).done(function (res) {
          count++;
          if (count == totalPieces) {
            console.log("上传结束,请求拼接接口,将切片信息拼接完整,返回图片url");
            $.post('/merge', { id: uuidfolder }, function (data) {
              console.log(data);
            })
          }

        }).fail(function (res) {
          console.log("上传失败")
        });
        start = end;
        index++;
      }
    }


    function uuid(len, radix) {
      var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
      var uuid = [], i;
      radix = radix || chars.length;

      if (len) {
        // Compact form
        for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
      } else {
        // rfc4122, version 4 form
        var r;

        // rfc4122 requires these characters
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
        uuid[14] = '4';

        // Fill in random data.  At i==19 set the high bits of clock sequence as
        // per rfc4122, sec. 4.1.5
        for (i = 0; i < 36; i++) {
          if (!uuid[i]) {
            r = 0 | Math.random() * 16;
            uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
          }
        }
      }

      return uuid.join('');
    }
  </script>
</body>

</html>
node
// 上传
router.post('/imgurl', upload.single('img'), function (req, res, next) {
  // req.file 是 `avatar` 文件的信息
  // req.body 将具有文本域数据,如果存在的话
  console.log(req.file)
  console.log(req.body)

  // 旧文件地址
  let imgOld = req.file.destination + "/" + req.file.filename
  // 新文件地址
  let imgNew = req.file.destination + "/" + req.body.name + '.' + 'blob-' + req.body.index;

  fs.rename(imgOld, imgNew, (err) => {
    if (err) {
      res.json({
        success: false,
        data: '上传失败'
      })
    } else {
      res.json({
        success: true,
        data: imgNew
      })
    }
  })
});

router.post('/file', async (ctx, next) => {
  // 根据hash值,获取分片文件。
  // 创建存储文件
  // 合并
  const chunksPath = path.join('uploads', '/');
  const filePath = path.join('uploads', 'cs.bin');
  // 读取所有的chunks 文件名存放在数组中
  // const chunks = fs.readdirSync(chunksPath);
  // 创建存储文件
  fs.writeFileSync(filePath, '');
  // if (chunks.length !== total || chunks.length === 0) {
  //   ctx.status = 200;
  //   ctx.res.end('切片文件数量不符合');
  //   return;
  // }
  for (let i = 0; i < 58; i++) {
    // 追加写入到文件中
    fs.appendFileSync(filePath, fs.readFileSync(chunksPath + 'cs.blob' + '-' + i));
    // 删除本次使用的chunk    
    fs.unlinkSync(chunksPath + 'cs.blob' + '-' + i);
  }
  // fs.rmdirSync(chunksPath);
  // // 文件合并成功,可以把文件信息进行入库。
  // ctx.status = 200;
  ctx.res.end('合并成功');


  console.log(chunksPath)
  console.log(filePath)
  // console.log(chunks)
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值