大文件上传

校验文件类型

  1. 根据文件后缀名判断

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /**
    * 校验文件名后缀
    * @param {String} fileName 文件名
    * @return {boolean} flag 文件后缀是否正确
    */
    checkSuffixes(fileName) {
    const SUFFIXES_PNG = 'PNG';
    return this.getSuffixes(fileName).toUpperCase() === SUFFIXES_PNG;
    },

    /**
    * 获取文件后缀名
    * @param {String} fileName 文件名
    * @return {string} suffixes 文件类型
    */
    getSuffixes(fileName) {
    if (!fileName) {
    return '';
    }
    return fileName.split('.').pop();
    }
  2. 根据文件内容判断

    以png图片为例,所有png图片开始的十六进制都为 89 50 4E 47。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    /**
    * 读取BASE64
    * @param {Blob} blob 需要读取的Blob
    * @return {Promise<>}
    */
    blobToHexadecimalString(blob) {
    return new Promise((resolve, reject) => {
    const render = new FileReader();
    render.onload = function () {
    const res = this.result
    .split('')
    .map(i => i.charCodeAt())
    .map(i => i.toString(16).toUpperCase())
    .map(i => i.padStart(2, '0'))
    .join(' ');
    resolve(res);
    }
    render.onerror = function () {
    this.abort();
    reject(this);
    }
    render.readAsBinaryString(blob);
    })
    },

    /**
    * 校验是否为PNG格式
    * @param {Blob} file
    * @return {boolean} flag 是否为PNG格式
    */
    async checkHexPNG(file) {
    const HEX_PNG = '89 50 4E 47';
    const str = await this.blobToHexadecimalString(file.slice(0, 4));
    return str === HEX_PNG;
    }

切片

将大文件切片成chunk,进行分片上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 生成切片
* @param file 需要生成切片的文件
* @param chunkSize 切片大小
* @return {[]} 切片数组
*/
createChunks(file, chunkSize = CHUNK_SIZE) {
const {size: fileSize} = file;
const chunks = [];
let index = 0;
while (index < fileSize) {
chunks.push({
index,
chunk: file.slice(index, index + chunkSize),
});
index += chunkSize;
}
return chunks;
}

计算MD5

  1. 直接计算md5

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /**
    * 直接计算md5
    * @param file 需要计算的文件
    * @return {Promise<*>}
    */
    async calculateHash(file) {
    const data = await this.blobToData(file);
    return md5(data);
    }
0%