| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 | let bucket; //aws上传接口let bucketname = "ccrb"; //桶const partsize = 5 * 1024 * 1024; // 5MB//--------------------------分断上传保证稳定性//初始化上传async function init() {    const credentials = {        accessKeyId: "AKIATLPEDU37QV5CHLMH",        secretAccessKey: "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",    }; //秘钥形式的登录上传    window.AWS.config.update(credentials);    window.AWS.config.region = "cn-northwest-1"; //设置区域    //桶的设置    bucket = new window.AWS.S3({        params: {            Bucket: bucketname        }    });    return bucket;}//初始化上传入口async function initMultipartUpload(key, file) {    const params = {        Bucket: bucketname,        Key: key,        ContentType: file.type,        "ACL": "public-read"    };    //创建一个续传通道    const data = await bucket.createMultipartUpload(params).promise();    return data.UploadId;}// 上传文件的某一部分async function uploadPart(file, keyname, uploadid, pn, start, end) {    //key可以设置为桶的相对路径,Body为文件, ACL最好要设置    var params = {        Bucket: bucketname,        Key: keyname,        PartNumber: pn,        UploadId: uploadid,        Body: file.slice(start, end)    };    const result = await bucket.uploadPart(params).promise();    return { ETag: result.ETag, PartNumber: pn };}// 完成分块上传async function completeMultipartUpload(parts, keyname, uploadid) {    const params = {        Bucket: bucketname,        Key: keyname,        MultipartUpload: { Parts: parts },        UploadId: uploadid    };    return await bucket.completeMultipartUpload(params).promise();}//中止分块上传async function abortMultipartUpload(key, uploadid) {    const params = {        Bucket: bucketname,        Key: key,        UploadId: uploadid    };    await bucket.abortMultipartUpload(params).promise();}// 实际的上传逻辑async function uploadFile(file, folderid) {    folderid = folderid || window.Guid.newGuid(); //分配到一个随机的id里    var keyname = folderid + "/" + file.name; //保存在指定的文件夹里    var uploadid = "";    try {        init(); // 初始化aws接口        // 初始化分块上传        uploadid = await initMultipartUpload(keyname, file);        // 分块上传文件        let parts = [];        let start = 0;        let end = 0;        let len = Math.ceil(file.length / partsize); //循环的长度        //循环上传        for (let i = 0; i < len; i++) {            start = i * partsize;            end = (i + 1) * partsize;            parts.push(await uploadPart(file, keyname, uploadid, i, start, end));        }        // 完成分块上传        await completeMultipartUpload(parts, keyname, uploadid);        return uploadid;    }    catch (error) {        // 如果出现错误,中止分块上传        console.error('An error occurred during file upload:', error);        await abortMultipartUpload(keyname, uploadid);    }}//--------------------------------下面支持断点续传//初始化亚马逊参数async function init() {    //秘钥形式的登录上传    const credentials = {        accessKeyId: "AKIATLPEDU37QV5CHLMH",        secretAccessKey: "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",        region: "cn-northwest-1"    };    window.AWS.config.update(credentials);    // window.AWS.config.region = "cn-northwest-1"; //设置区域    //桶的设置    bucket = new window.AWS.S3({        params: {            Bucket: bucketname        }    });    return bucket;}//获取当前文件是否有已上传断点信息async function getawscheckpoint(key) {    let partsinfo;    try {        const result = await bucket.listMultipartUploads({ Bucket: bucketname, Prefix: key }).promise();        //获取具体分片信息        if (result.Uploads.length) {            uploadid = result.Uploads[result.Uploads.length - 1].UploadId;            partsinfo = await bucket.listParts({ Bucket: bucketname, Key: key, UploadId: uploadid, }).promise();        }    } catch (err) {        console.log(err);    }    return { uploadid, partsinfo };}//分段上传async function awsuploadpart(filestate, file, uploadid, parts, key) {    var partarr = [];//已完成的数组    //已完成的分片,转化成提交格式    const completeparts = parts.map((_) => {        partarr.push(_.PartNumber);        return { PartNumber: _.PartNumber, ETag: _.ETag };    });    // 分块上传文件    let uploadpart;    let start = 0;    let end = 0;    let len = Math.ceil(file.size / partsize); //循环的长度    if (partarr.length) {        filestate.status = "processing";        filestate.percent = parseInt((completeparts.length * 100) / len);    }    //循环上传    for (let i = 0; i < len; i++) {        start = i * partsize;        end = (i + 1) * partsize;        if (!partarr.includes(i)) {            uploadpart = await uploadPart(file, key, uploadid, i + 1, start, end);            if (uploadpart.ETag != null) {                completeparts.push(uploadpart);                filestate.percent = parseInt((completeparts.length * 100) / len);            }            else {                filestate.status = "fail";                return;            }        }    }    //提交上传成功信息    var data = await completeMultipartUpload(completeparts, key, uploadid);    filestate.status = "success";    return data;}//上传的接口async function awsupload(file, folderid, filestate) {    init(); //初始化桶    const key = (folderid || window.Guid.newGuid()) + "/" + file.name; //需要上传的文件名    filestate.percent = 0;    filestate.status = "start";    //上传的参数    var params = {        Bucket: bucketname,        Key: key    };    //设置桶上传文件    try {        //检查文件是否已上传        bucket.headObject(params, async (err, data) => {            // 没有上传成功,head方法会返回失败            if (err) {                //检查是否部分上传                const { uploadid, partsinfo } = await getawscheckpoint(key, bucket);                //如果已经部分存在,那么直接在节点续传                if (uploadid) {                    //断点续传                    var data = await awsuploadpart(filestate, file, uploadid, partsinfo.Parts, key);                    return { data, key, uploadid };                }                //不存在,上传新的                else {                    const uploadid = await initMultipartUpload(key, file); //初始化文件上传                    var data = await awsuploadpart(filestate, file, uploadid, [], key);                    return { data, key, uploadid };                }            }            //如果已经上传成功了,那么直接返回状态百分百            else if (data) {                //data存在,上传成功                filestate.percent = 100;                filestate.status = "success";                return { data, key };            }        });    }    catch (err) {        filestate.status = "error";        console.log(err);    }}
 |