我想在上传到七牛云之前本地计算下hash来对比文件是否已存在
vue框架使用的是element-ui
计算方式使用的是七牛云官方提供的qetag.js
upload.vue
import qetag from '../assets/js/qetag'
methosd: {
beforeAvatarUpload(file) {
qetag(file,function(hash) {
console.log(hash)
})
}
}
qetag.js
// 计算文件的eTag,参数为buffer或者readableStream或者文件路径
function getEtag(buffer,callback){
// 判断传入的参数是buffer还是stream还是filepath
let mode = 'buffer';
if(typeof buffer === 'string'){
buffer = require('fs').createReadStream(buffer);
mode='stream';
}else if(buffer instanceof require('stream')){
mode='stream';
}
// sha1算法
let sha1 \= function(content){
let crypto \= require('crypto');
let sha1 = crypto.createHash('sha1');
sha1.update(content);
return sha1.digest();
};
// 以4M为单位分割
let blockSize = 4\*1024\*1024;
let sha1String = \[\];
let prefix = 0x16;
let blockCount = 0;
switch(mode){
case 'buffer':
var bufferSize = buffer.length;
blockCount = Math.ceil(bufferSize / blockSize);
for(let i=0;i<blockCount;i++){
sha1String.push(sha1(buffer.slice(i\*blockSize,(i+1)\*blockSize)));
}
process.nextTick(function(){
callback(calcEtag());
});
break; case 'stream':
var stream = buffer;
stream.on('readable', function() {
let chunk;
// eslint-disable-next-line no-cond-assign
while (chunk = stream.read(blockSize)) {
sha1String.push(sha1(chunk));
blockCount++
}
})
stream.on('end',function(){
callback(calcEtag())
})
break
}
function calcEtag(){
if(!sha1String.length){
return 'Fto5o-5ea0sNMlW\_75VgGJCv2AcJ';
}
let sha1Buffer = Buffer.concat(sha1String,blockCount \* 20);
// 如果大于4M,则对各个块的sha1结果再次sha1
if(blockCount > 1){
prefix = 0x96;
sha1Buffer = sha1(sha1Buffer);
}
sha1Buffer = Buffer.concat(
\[new Buffer(\[prefix\]),sha1Buffer\],
sha1Buffer.length \+ 1
)
return sha1Buffer.toString('base64')
.replace(/\\//g,'\_').replace(/\\+/g,'-')
}
}
module.exports \= getEtag
计算不到结果,一直返回 Fto5o-5ea0sNMlW_75VgGJCv2AcJ
请问是为什么?
看到
require('fs')
这应该是个 node.js 的库吧?你放到浏览器里跑不起来的,返回固定值也是合理的。解决方案:
FileReader
+ 其它支持浏览器的加解密库