layui对接阿里云OSS对象存储分片上传
| web前端
评论 0 | 点赞 0 | 浏览 382

你没看错,即将2022年了,还有人在使用layui......

辣鸡公司......😩

1、首先,去github下载阿里云oss的sdk(https://github.com/ali-sdk/ali-oss?spm=5176.12818093.help.30.5adc16d0eSeC1k),只需要dist文件夹中aliyun-oss-sdk.min.js即可。

2、把aliyun-oss-sdk.min.js放到start目录下,代码里引入

<script src="./aliyun-oss-sdk.min.js"></script>

3、由于是大文件的分片上传,因此这里做个进度条,显得友好。

<div class="layui-form-item">
            <label class="layui-form-label">回放链接:</label>
            <div class="layui-input-block">
                <div style="display: flex;align-items: center">
                    <input type="text" name="playBackUrl" id="playBackUrl" autocomplete="off" class="layui-input"
                           placeholder="请输入回放链接" style="width: 70%; display: inline-block;"/>
                    <a href="javascript:;" class="file" id="a-file">上传回放视频
                        <input type="file" id="oss-input"/>
                    </a>
                    <div id="file-progress" style="display: none;width: 25%;margin-left: 10px;">
                        <div style="display: flex;align-items: center;">
                            <div class="layui-progress" lay-showPercent="true" lay-filter="upload-progress" style="width: 80%">
                                <div class="layui-progress-bar layui-bg-red" lay-percent="0%" style="width: 0%">
                                    <span class="layui-progress-text">0%</span>
                                </div>
                            </div>
                            <button id="upload-cancel" class="layui-btn layui-btn-sm" style="margin-left: 10px;">取消</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

css样式:

.file {
        position: relative;
        display: inline-block;
        background: #D0EEFF;
        border: 1px solid #99D3F5;
        border-radius: 4px;
        padding: 4px 12px;
        overflow: hidden;
        color: #1E88C7;
        text-decoration: none;
        text-indent: 0;
        line-height: 20px;
        margin-left: 20px;
    }
    .file input {
        position: absolute;
        font-size: 100px;
        right: 0;
        top: 0;
        opacity: 0;
    }
    .file:hover {
        background: #AADFFD;
        border-color: #78C3F3;
        color: #004974;
        text-decoration: none;
    }

4、js里面写个change事件,监听文件上传。

$("#oss-input").change(function () {
                                let val = $("#oss-input").val()
                                if (val === null || val === '') {
                                    return;
                                }
                                admin.postReq({
                                    url: 'api/oss/getSTSToken',
                                    data: {},
                                    dfunc: function (res) {
                                        $('#a-file').hide();
                                        $('#file-progress').show();
                                        element.progress('upload-progress', '0%');
                                        const client = new OSS({
                                            // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
                                            region: res.data.region,
                                            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
                                            accessKeyId: res.data.accessKeyId,
                                            accessKeySecret: res.data.accessKeySecret,
                                            // 从STS服务获取的安全令牌(SecurityToken)。
                                            stsToken: res.data.securityToken,
                                            // 填写Bucket名称,例如examplebucket。
                                            bucket: res.data.bucket,
                                            // 刷新临时访问凭证的方法
                                            refreshSTSToken: async () => {
                                                // 向您搭建的STS服务获取临时访问凭证。
                                                return await getSTSToken();
                                            },
                                            // 刷新临时访问凭证的时间间隔,单位为毫秒。
                                            refreshSTSTokenInterval: 1000 * 60 * 10
                                        });
                                        let file = $("#oss-input").get(0).files[0]                    //上传路径自己定义
                                        let filePath = '/xxx/'  + file.name;
                                        //取消上传
                                        $('#upload-cancel').click(function () {
                                            client.cancel();
                                            $('#file-progress').hide()
                                            $('#a-file').show();
                                        })
                                        multipartUpload(file, filePath, client).then(result=>{
                                            if (result.res.status !== 200) {
                                                layer.msg("上传失败")
                                            } else {
                                                let path = 'http://xxxxx.com' + result.name;//这里可以拼接cdn的地址,也可以直接用阿里云返回的访问地址
                                                $('#playBackUrl').val(encodeURI(path))
                                                $('#file-progress').hide()
                                                $('#a-file').show();
                                                layer.msg("上传成功")
                                            }
                                        })
                                    }
                                })

                                async function multipartUpload (file, filePath, client) {
                                    try {
                                        // 您可以通过自定义文件名(例如exampleobject.txt)或目录(例如exampledir/exampleobject.txt)的形式,实现将文件上传到当前Bucket或Bucket中的指定目录。
                                        return await client.multipartUpload(filePath, file, {
                                            progress: function (p, checkpoint) {
                                                // checkpoint参数用于记录上传进度,断点续传上传时将记录的checkpoint参数传入即可。浏览器重启后无法直接继续上传,您需要手动触发上传操作。
                                                let pecent = parseInt(parseFloat(p) * 100);                        //更新进度条<br/>                                                element.progress('upload-progress', pecent + '%');
                                            },
                                            parallel: 4,
                                            // 设置分片大小。默认10 MB,最小值为100 KB。
                                            partSize: 1024 * 1024 * 10
                                        });
                                    } catch(e){
                                        console.log(e);
                                        if (e.name === 'SecurityTokenExpiredError') {
                                            layer.msg("临时秘钥已过期,上传失败")
                                        } else if(e.name === 'cancel') {
                                            layer.msg("已取消上传")
                                        } else {
                                            layer.msg("出现异常,上传失败")
                                        }
                                    }
                                }

                            })//刷新临时访问凭证的方法function getSTSToken() {
            return new Promise((resolve, reject) => {
                let secret = {};
                admin.postReq({
                    url: '/api/oss/getSTSToken',
                    data: {},
                    success: function (res) {
                        if (res.data) {
                            secret.region=res.data.region
                            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
                            secret.accessKeyId=res.data.accessKeyId
                            secret.accessKeySecret=res.data.accessKeySecret
                            // 从STS服务获取的安全令牌(SecurityToken)。
                            secret.stsToken=res.data.securityToken
                            // 填写Bucket名称,例如examplebucket。
                            secret.bucket=res.data.bucket
                            resolve(secret)
                        } else {
                            reject([])
                        }
                    }
                })
            })
        }<br/>

对于大文件的上传,强烈建议定义refreshSTSToken来定时刷新临时访问凭证,避免凭证过期导致文件上传一半报错。

关于生成临时访问凭证的接口怎么写就不啰嗦了,相信咱们后端程序员都能搞定

5、效果:


上传完成后,链接会自动填入到表单


6、总结:layui真难用😞

本文作者:不是好驴
本文链接:https://www.baddonkey.cn/detail/24
版权声明:原创文章,允许转载,转载请注明出处

高谈阔论

留言列表