Oct1a

理解并实现秒传功能

大众化的网盘都支持秒传,如我们国内人都听惯的金山,出的金山快盘就有这个功能,还有金山T盘、RF、纳米、115,国内的360安全厂商也出品了360云盘,百度出品的百度网盘,腾讯打造出的微云同样运用了“秒传”技术。

​ 秒传是一种在网盘上常见的“忽略式”上传方式,就是您上传了一个文件名为111.exe,MD5为一个数,有一个网友以前也上传一个叫111.exe,MD5和您上传的文件 MD5 码一模一样,所以这个文件上传到服务器上的时间就很短了,这是因为别人上传过这个文件,您上传这个文件,服务器上有这个文件了,所以只需要把这个文件链接一份到您的网盘上就可以了。就好比,别人叫你做过这件事情,又有人今天找你来让你做这件事情,你是不是有一点经验,会很熟练,做的时间就快多了?在这里也是同理。

提示:更改文件名、扩展名、存放路径、其他属性都不会改变MD5值,只有在更改文件内容情况下,md5跟哈希值才会变化

想要执行此功能,后端需要重新写一个接口/verify

if (req.url === "/verify") {
  const data = await resolvePost(req);
  const { fileName } = data;
  const filePath = path.resolve(UPLOAD_DIR, fileName);
  if (fse.existsSync(filePath)) {
    res.end(
      JSON.stringify({
        shouldUpload: false
      })
    );
  } else {
    res.end(
      JSON.stringify({
        shouldUpload: true
      })
    );
  }
}

前端在上传文件步骤也要做拦截:

async handleUpload() {
      const fileObj = this.fileObj;
      if (!fileObj.file) return;
      const { shouldUpload } = await this.verifyUpload(
         fileObj.file.name,
       );
       if (!shouldUpload) {
         alert("秒传:上传成功");
         return;
       }
      const chunkList = this.createChunk(fileObj.file);
      this.fileObj.chunkList = chunkList.map(({ file }, index) => ({
        file,
        size: file.size,
        percent: 0,
        chunkName: `${fileObj.file.name}-${index}`,
        fileName: fileObj.file.name,
        index,
      }));
      this.uploadChunks();
    },
 async verifyUpload (fileName) {
       const { data } = await this.axiosRequest({
         url: "http://localhost:3000/verify",
         headers: {
           "content-type": "application/json",
         },
         data: JSON.stringify({
           fileName,
         }),
       });
       return data
     }

现在我们重新上传文件,因为服务器上已经存在该文件了,所以,直接显示秒传:上传成功

截屏2021-07-09 下午2.17.02.png

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。