​​减轻服务器压力:如何为 CKEditor 4 实现阿里云 OSS 前端直传​
本文最后更新于5 天前

html5video_v1插件介绍

项目介绍

最近用到ckeditor的视频上传插件 html5video,默认是通过配置一个上传地址来上传视频文件,不够灵活,且没有汉化。
这个项目基于插件html5video原插件链接),通过部分修改实现了上传的自由定制,以及汉化处理

软件架构

1.默认选中自适应宽度,隐藏高宽设置,以及高级设置

图片信息,默认选中自适应宽度,隐藏高宽设置,以及高级设置

2.上传界面

上传界面

安装教程

  1. 复制html5video_v1文件夹到{ckeditor_home}/plugins 文件夹下

使用说明

  1. {ckeditor_home}/config.js 添加 config.extraPlugins = 'html5video_v1',config.toolbar 里边添加 “Html5video_v1”
  2. 页面初始化editor,调用replace方法时:
CKEDITOR.replace( 'editor',{
    html5video_v1UploadFn:function(file,callback){
            uploadFile(file,callback);
        }
});

上传逻辑

引用上传组件

    <script src='https://gosspublic.alicdn.com/aliyun-oss-sdk-6.18.0.min.js'></script>

前端上传到 oss

    function uploadFile(file, callback) {
        const ext = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase();
        console.log(file.name, ext, file)

        // 限制文件大小 视频
        if (ext === 'mp4') {
            if (file.size > 1024 * 1024 * 200) {
                alert('文件过大,请选择小于200M的文件!');
                return;
            }
        } else if (file.size > 1024 * 1024 * 10) {
            alert('文件过大,请选择小于10M的文件!');
            return;
        }

        var xhr, formData;
        console.log(file.name);
        xhr = new XMLHttpRequest();
        xhr.withCredentials = false;
        xhr.open('GET', "/admin/alibaba_sts_token");
        xhr.onload = function () {
            var stsTokenJson;
            if (xhr.status !== 200) {
                alert('HTTP Error: ' + xhr.status);
                return;
            }
            stsTokenJson = JSON.parse(xhr.responseText);
            if (!stsTokenJson) {
                alert('Invalid JSON: ' + xhr.responseText);
                return;
            }
            console.log(stsTokenJson)

            const client = new OSS({
                // yourRegion填写Bucket所在地域。以华东1(杭州)为例,yourRegion填写为oss-cn-hangzhou。
                region: stsTokenJson.OssRegion,
                authorizationV4: true,
                // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
                accessKeyId: stsTokenJson.Credentials.AccessKeyId,
                accessKeySecret: stsTokenJson.Credentials.AccessKeySecret,
                // 从STS服务获取的安全令牌(SecurityToken)。
                stsToken: stsTokenJson.Credentials.SecurityToken,
                // 填写Bucket名称。
                bucket: stsTokenJson.OssBucket,
            });

            // 从输入框获取file对象,例如<input type="file" id="file" />。
            let data = new File([file], file.name, {
                type: file.type,
                lastModified: file.lastModified
            });
            // 创建并填写Blob数据。
            //const data = new Blob(['Hello OSS']);
            // 创建并填写OSS Buffer内容。
            //const data = new OSS.Buffer(['Hello OSS']);

            const ext = file.name.split('.').pop();
            // 随机文件名 字母+随机数
            const filename = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + '.' + ext;
            // /年/月/日/文件名
            const objectName = new Date().getFullYear() + '/' + (new Date().getMonth() + 1) + new Date().getDate() + '/' + filename;
            const ossHost = stsTokenJson.OssHost;

            const headers = {
                // 指定该Object被下载时的网页缓存行为。
                'Cache-Control': 'no-cache',
                // 指定该Object被下载时的名称。
                'Content-Disposition': filename,
                // 指定该Object被下载时的内容编码格式。
                'Content-Encoding': 'utf-8',
                // 指定过期时间,单位为毫秒。
                Expires: '1000',
                // 指定Object的存储类型。
                'x-oss-storage-class': 'Standard',
                // 指定Object标签,可同时设置多个标签。
                // 'x-oss-tagging': 'Tag1=1&Tag2=2',
                // 指定初始化分片上传时是否覆盖同名Object。此处设置为true,表示禁止覆盖同名Object。
                'x-oss-forbid-overwrite': 'true',
            };

            // 指定上传到examplebucket的Object名称,例如exampleobject.txt。
            const options = {
                // 获取分片上传进度、断点和返回值。
                progress: (p, cpt, res) => {
                    console.log(p, cpt, res);
                    // uploadRef.value.uploadFilePercent({
                    //   file,
                    //   percent: (p * 100).toFixed(2),
                    // });
                    let process = (p * 100).toFixed(2)
                    if (process < 100) {
                        document.getElementsByClassName("cke_dialog_ui_fileButton cke_dialog_ui_button")[0].innerHTML = "正在上传中..." + process + "%";
                    } else {
                        document.getElementsByClassName("cke_dialog_ui_fileButton cke_dialog_ui_button")[0].innerHTML = "上传";
                    }
                },
                // 设置并发上传的分片数量。
                parallel: 4,
                // 设置分片大小。默认值为1 MB,最小值为100 KB。
                partSize: 1024 * 1024,
                // headers,
                // 自定义元数据,通过HeadObject接口可以获取Object的元数据。
                meta: {
                    // year: 2020, people: 'test'
                },
                mime: 'text/plain',
            };

            async function putObject(objectName, data, options) {
                try {
                    // 填写Object完整路径。Object完整路径中不能包含Bucket名称。
                    // 您可以通过自定义文件名(例如exampleobject.txt)或文件完整路径(例如exampledir/exampleobject.txt)的形式实现将数据上传到当前Bucket或Bucket中的指定目录。
                    // data对象可以自定义为file对象、Blob数据或者OSS Buffer。
                    console.log("data", data, objectName, options, data instanceof File)
                    const result = await client.multipartUpload(objectName, data, options);
                    console.log(result);
                    // callback(ossHost + "/" + objectName, {title: file.name});
                    callback(ossHost + "/" + objectName);
                } catch (e) {
                    console.log(e);
                }
            }

            putObject(objectName, data, options)

        };
        formData = new FormData();
        xhr.send(formData);
    }

安装laravel sts 扩展

composer require alibabacloud/sts-20150401

后端获取临时授权token

    public function getSecurityToken()
    {
//        if (Cache::has('alibaba_security_token')) {
//            $token = Cache::get('alibaba_security_token');
//            return $token;
//        }

        $bucket = env('ALIYUN_OSS_BUCKET');

        $client            = AlibabaClients::createStsClient();
        $assumeRoleRequest = new AssumeRoleRequest([
            "durationSeconds" => 3600,
            "roleArn"         => "acs:ram::1051028462152558:role/ramoss",
            "roleSessionName" => "RAMOSS",
            "Policy"          => json_encode([
                "Statement" => [
                    [
                        "Action"   => "oss:PutObject",
                        "Effect"   => "Allow",
                        "Resource" => "acs:oss:*:*:${bucket}/*"
                    ]
                ],
                "Version"   => "1"
            ])
        ]);
        $runtime           = new RuntimeOptions([]);
        // 复制代码运行请自行打印 API 的返回值
        $resp = $client->assumeRoleWithOptions($assumeRoleRequest, $runtime);

        $body = $resp->toMap()['body'] ?? [];

        $body['OssRegion'] = env('ALIYUN_OSS_REGION');
        $body['OssBucket'] = $bucket;
        $body['OssHost']   = env('ALIYUN_OSS_HOST');

        Cache::put('alibaba_security_token', $body, 3600);
        return $body;
    }


扫码关注,及时关注技术动态


暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇