OSS网页上传和断点续传(终结篇)

本文介绍如何使用阿里云OSS的BrowserJS-SDK实现文件上传和断点续传功能,通过保存上传断点到OSS,实现无论在网络中断、浏览器关闭甚至更换设备的情况下继续完成文件上传。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有了之前OSS网页上传和断点续传(OSS配置篇)和(STSToken篇),其万事俱备只欠东风啦,此终结篇即将展示OSS上传文件及断点续传的无限魅力...

网络卡顿、延迟能续传吗?能!

关了浏览器,还能续传吗?能!!

关了电脑,还能续传吗?能!!!

关了电脑、跑到异地去,还能续传吗?能!!!!

这么屌?就是这么屌!下面就看看是不是这么屌!

1、下载OSS的BrowserJS-SDK文件aliyun-oss-sdk-5.2.0.min.js,在此引用5.2.0版本

下载地址:https://github.com/ali-sdk/ali-oss/tree/release/5.2.0

引用aliyun-oss-sdk-5.2.0.min.js和jquery文件即可

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Res/aliyun-upload-sdk-1.4.0/aliyun-oss-sdk-5.2.0.min.js"></script>

2、HTML代码

    <div id="up_wrap"></div>
    <div class="form-group">
        <input type="file" id="file" multiple="multiple" />
    </div>
    <div class="form-group">
        <input type="button" class="btn btn-primary" id="file-button" value="Upload" />
        <input type="button" class="btn btn-primary" id="Continue-button" value="Continue" />
    </div>

3、文件上传和断点续传代码

<script type="text/javascript">
        var appServer = 'http://localhost:87/STS/Token';
        var bucket = 'cactus-open';
        var region = 'oss-cn-hangzhou';
        var uid = 'x';//用户标识
        var urllib = OSS.urllib;
        var Buffer = OSS.Buffer;
        var OSS = OSS.Wrapper;
        //获取授权STSToken,并初始化client
        var applyTokenDo = function (func) {
            var url = appServer;
            return urllib.request(url, {
                method: 'GET'
            }).then(function (result) {
                var creds = JSON.parse(result.data);
                var client = new OSS({
                    region: region,
                    accessKeyId: creds.AccessKeyId,
                    accessKeySecret: creds.AccessKeySecret,
                    stsToken: creds.SecurityToken,
                    bucket: bucket
                });
                return func(client);
            });
        };
        //上传文件
        var uploadFile = function (client) {
            if (upfiles.length < 1)
                return;
            upfile = upfiles[0];
            var file = upfile.file;
            var key = upfile.name;
            var objkey = key + "_" + uid + ".json";
            return client.multipartUpload(key, file, {
                progress: function (p, cpt, res) {
                    console.log("p:", p);
                    console.log("cpt:", cpt);
                    if (cpt != undefined) {
                        var content = JSON.stringify(cpt);
                        client.put(objkey, new Buffer(content));
                    }
                    return function (done) {
                        var bar = document.getElementById('progress-bar_' + upfile.num);
                        bar.style.width = Math.floor(p * 100) + '%';
                        bar.innerHTML = Math.floor(p * 100) + '%';
                        done();
                    }
                }
            }).then(function (res) {
                console.log('upload success: ', res);
                upfiles.shift();
                client.delete(objkey);                
                applyTokenDo(uploadFile);
            });
        };
        //断点续传文件
        var reUploadFile = function (client) {
            if (upfiles.length < 1)
                return;
            upfile = upfiles[0];
            var file = upfile.file;
            var key = upfile.name;
            var objkey = key + "_" + uid + ".json";
            return client.get(objkey).then(function (res) {
                var data = JSON.parse(res.content);
                data.file = file;
                return client.multipartUpload(key, file, {
                    checkpoint: data,
                    progress: function (p, cpt, res) {
                        console.log("p:", p);
                        console.log("cpt:", cpt);
                        if (cpt != undefined) {
                            var content = JSON.stringify(cpt);
                            store.put(objkey, new Buffer(content));
                        }
                        return function (done) {
                            var bar = document.getElementById('progress-bar_' + upfile.num);
                            bar.style.width = Math.floor(p * 100) + '%';
                            bar.innerHTML = Math.floor(p * 100) + '%';
                            done();
                        }
                    }
                }).then(function (ret) {
                    console.log('upload success:', ret);
                    upfiles.shift();
                    client.delete(objkey);                    
                    applyTokenDo(uploadFile);
                });
            });
        };
        //文件上传队列
        var upfiles = [];

        $(function () {
            //初始化文件上传队列
            $("#file").change(function (e) {
                var ufiles = $(this).prop('files');
                var htm = "";
                for (var i = 0; i < ufiles.length; i++) {
                    htm += "<dl><dt>" + ufiles[i].name + "</dt><dd><div class=\"progress\"><div id=\"progress-bar_" + i + "\" class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"0\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"min-width: 2em;\">0%</div></div></dd></dl>";
                    upfiles.push({
                        num: i,
                        name: ufiles[i].name,
                        file: ufiles[i]
                    })
                }
                console.log('upfiles:', upfiles);
                $("#up_wrap").html(htm);
            })
            //上传
            $("#file-button").click(function () {
                applyTokenDo(uploadFile);
            })
            //续传
            $("#Continue-button").click(function () {
                applyTokenDo(reUploadFile);
            })
        })
    </script>

^_^^_^!代码这么少,效果这么好,原来这么屌!上图:

单个文件、多个文件,小文件、大文件,随便来!!

原理很简单,把上传断点保存在OSS中,不管怎么断网、关浏览器、关电脑.....。统统不管,都能上传。当上传完毕后,会自动删掉保存断点的文件。

 

### 阿里云OSS 分片上传 断点续传 实现方式 为了实现阿里云OSS中的分片上传断点续传功能,可以遵循以下逻辑设计技术要点: #### 初始化分片上传任务 在开始上传之前,需调用 `InitiateMultipartUpload` 接口来初始化一个多部分上传任务。此操作会返回一个唯一的 Upload ID,该 ID 是后续所有分片上传请求的关键标识[^1]。 ```python import oss2 auth = oss2.Auth('your-access-key-id', 'your-access-key-secret') bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', 'your-bucket-name') # 初始化分片上传 init_result = bucket.init_multipart_upload('object-name') upload_id = init_result.upload_id ``` #### 记录已上传的分片信息 要支持断点续传,必须记录已经成功上传的分片编号及其对应的 ETag 值。ETag 是 OSS 返回的一个唯一字符串,用于确认某个分片是否已被成功上传。可以通过本地文件或数据库保存这些元数据。 如果程序意外中断,在恢复时可以根据存储的信息跳过已完成的部分,仅重新上传未完成的分片。 #### 并发上传分片 使用 `UploadPart` 接口逐一分片上传OSS。每个分片都有其独立的 Part Number Data 数据流。注意控制并发数量以优化性能,避免因过多线程导致资源争抢或网络拥塞。 ```python from concurrent.futures import ThreadPoolExecutor def upload_part(part_number, data_chunk): result = bucket.upload_part('object-name', upload_id, part_number, data_chunk) return {'part_number': part_number, 'etag': result.etag} parts_info = [] with ThreadPoolExecutor(max_workers=5) as executor: futures = [ executor.submit(upload_part, i + 1, chunk_data) for i, chunk_data in enumerate(file_chunks) ] for future in futures: parts_info.append(future.result()) ``` #### 完成分片合并 当所有分片都成功上传后,调用 `CompleteMultipartUpload` 接口提交完整的分片列表给 OSS,从而将它们合成为一个最终的对象。此时需要提供按顺序排列好的各分片信息数组作为参数传递过去[^1]。 ```xml <CompleteMultipartUpload> <Part> <PartNumber>1</PartNumber> <ETag>"etag-value"</ETag> </Part> ... </CompleteMultipartUpload> ``` #### 处理异常情况 对于可能发生的错误场景比如超时、连接失败等问题,则应该捕获相应异常并采取重试机制或者手动干预手段解决;另外还可以设置定时器定期检查是否有长时间停滞的任务以便及时清理无用残留片段以防浪费存储空间。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值