理解并实现秒传功能
大众化的网盘都支持秒传,如我们国内人都听惯的金山,出的金山快盘就有这个功能,还有金山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
}
现在我们重新上传文件,因为服务器上已经存在该文件了,所以,直接显示秒传:上传成功
本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。