登录 立即注册

首页 > 绿虎论坛 > 网页插件 (发帖)

标题: [精][网页插件]🚀图文快贴阿里云OSS直传版

作者: @Ta

时间: 2021-08-05发布,2023-03-24修改

点击: 77521

改自 @水木易安 的图文快贴插件,原帖:https://hu60.cn/q.php/bbs.topic.97322.html

通过虎绿林附件前端表单直传API实现了直接向阿里云OSS上传文件,避免经过虎绿林web服务器中转,大大提高了上传速度。
而且如果你多次上传同一个文件,还可以实现“秒传”,第二次不需要重新上传即可获得下载链接。

此外,该插件也是用虎绿林附件前端表单直传API进行文件上传的参考实现。


使用方法

把以下代码导入到网页插件即可:

导入网页插件:图文快贴(当前用户:17,总安装次数:22)
<script src="/tpl/classic/js/SparkMD5/spark-md5.min.js"></script>
<script src="/tpl/classic/js/humanize/humanize.js"></script>
<script src="api.webplug-file.1_public_quick_paste_oss.js"></script>

然后就能用这个🚀图文快贴按钮上传附件了。

IMG_20210807_004048.jpg


附完整代码(供插件开发者参考,不建议直接使用,因为太长了)

<script src="/tpl/classic/js/SparkMD5/spark-md5.min.js"></script>
<script src="/tpl/classic/js/humanize/humanize.js"></script>
<script>
/**图文拖拽快传插件开始**/
$(function () { // 【😭😭😭】
    // 粘贴
    document.addEventListener('paste', function (event) {
        var clipboardData = (event.clipboardData || event.originalEvent.clipboardData);
        var files = [];
        for (var i=0; i<clipboardData.items.length; i++) {
            var file = clipboardData.items[i];
            if (file.kind === 'file') {
                var file = file.getAsFile();
                if (file) {
                    files.push(file);
                }
            }
        }
        if (files.length > 0) {
            resolveFileList(files);
        }
    });

    // 拖放
    var content = document.getElementById('content');
    if(!content) return '😥非帖子页面不继续执行';
    content.ondragover = function (ev) {
        ev.preventDefault();
        this.style.backgroundColor = '#ddd';
    }
    content.ondragleave = function () {
        this.style.backgroundColor = 'inherit';
    }
    content.ondrop = function (ev) {
        this.style.backgroundColor = 'inherit';
        ev.preventDefault();
        resolveFileList(ev.dataTransfer.files);
    }

    // 添加按钮
    var fastUpBtn = document.createElement('input');
    fastUpBtn.id = 'fastUpBtn';
    fastUpBtn.style.display = 'none';
    fastUpBtn.type = 'file';
    fastUpBtn.onchange = function (e) {
        resolveFileList(e.target.files);
    }
    var triggerUpBtn = document.createElement('input');
    triggerUpBtn.style.marginLeft = '4px';
    triggerUpBtn.type = 'button';
    triggerUpBtn.value = '🚀图文快贴';
    triggerUpBtn.onclick = function () {
        fastUpBtn.click()
    }
    // $("#add_files").after(fastUpBtn).after(triggerUpBtn);
    $("#ubbHelp").before(fastUpBtn).before(triggerUpBtn);

    // 上传文件
    function resolveFileList(files) {
        Array.from(files).forEach(file => {
            if (file.type.indexOf('text') === 0 || file.name.indexOf('.md') === file.name.length - 3) {
                file.text().then(text => {
                    insertText(content, text)
                });
            } else {
                uploadFile(file);
            }
        })
    }

    function insertText(obj, str) {  
        if (document.selection) {  
            var sel = document.selection.createRange();  
            sel.text = str;  
        } else if (typeof obj.selectionStart === 'number' && typeof obj.selectionEnd === 'number') {  
            var startPos = obj.selectionStart,  
                endPos = obj.selectionEnd,  
                cursorPos = startPos,  
                tmpStr = obj.value;  
            obj.value = tmpStr.substring(0, startPos) + str + tmpStr.substring(endPos, tmpStr.length);  
            cursorPos += str.length;  
            obj.selectionStart = obj.selectionEnd = cursorPos;  
        } else {  
            obj.value += str;  
        }  
    }

    function Toast(msg, duration) {
        console.log(msg)
        // 如果不需要提示框,请删除下面的代码
        duration = isNaN(duration) ? 2000 : duration;
        var m = document.createElement('div');
        m.innerHTML = msg;
        m.style.cssText = "max-width:60%;min-width: 150px;padding:0 14px;min-height: 40px;color: rgb(255, 255, 255);line-height: 40px;text-align: center;border-radius: 4px;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 999999;background: rgba(0, 0, 0,.7);font-size: 16px;";
        document.body.appendChild(m);
        setTimeout(function () {
            var d = 0.5;
            m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
            m.style.opacity = '0';
            setTimeout(function () {
                document.body.removeChild(m)
            }, d * 1000);
        }, duration);
        // 如果不需要提示框,请删除上面的代码
    }

    function md5sum(file) {
        var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
        var chunkSize = 2097152;
        var chunks = Math.ceil(file.size / chunkSize);
        var currentChunk = 0;
        var spark = new SparkMD5.ArrayBuffer();
        var fileReader = new FileReader();
        var deferred = $.Deferred();
        fileReader.onload = function (e) {
            spark.append(e.target.result);
            currentChunk++;
            if (currentChunk < chunks) {
                loadNext();
            } else {
                deferred.resolve(spark.end());
            }
        };
        fileReader.onerror = function (error) {
            deferred.reject(error);
        };
        function loadNext() {
            var start = currentChunk * chunkSize;
            var end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
            fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
        }
        loadNext();
        return deferred.promise();
    }

    async function uploadFile(file) {
        try {
            Toast('计算文件MD5');
            var md5 = await md5sum(file);
            console.log('md5', md5);

            Toast('获取上传凭证');
            var uploadForm = await $.post('/q.php/api.upload-form.json', {
                name: file.name,
                size: file.size,
                md5: md5
            });
            console.log('uploadForm', uploadForm);

            if (uploadForm.error) {
                Toast(uploadForm.errInfo.message);
                return;
            }

            if (uploadForm.fileExists) {
                Toast('已秒传');
                insertText(document.getElementById("content"), uploadForm.contentUbb);
                return;
            }

            // 准备表单
            var fd = new FormData();
            // 填充API返回的内容
            for (var k in uploadForm.formData) {
                fd.append(k, uploadForm.formData[k]);
            }
            // 填充待上传的文件
            fd.append(uploadForm.fileFieldName, file);

            Toast("开始上传");
            await $.ajax({
                type: uploadForm.method,
                url: uploadForm.requestUrl,
                data: fd,
                processData: false,
                contentType: false,
                mimeType: uploadForm.enctype,
            })
            
            Toast("上传成功");
            insertText(document.getElementById("content"), uploadForm.contentUbb);
        } catch (ex) {
            console.log(ex);
            Toast("上传失败\n" + JSON.stringify(ex));
        }
    }

}); // 【😭😭😭】
/**图文拖拽快传插件结束**/
</script>

[隐藏样式|查看源码]


『回复列表(24|隐藏机器人聊天)』

1.

老虎给力,不过上传完的时候不验证返回结果的吗

(/@Ta/2021-08-05 03:02//)

2.

@000,结果是HTTP 204无内容,await后得到undefined。如果上传出错,状态码不是2xx,await会抛出异常。

(/@Ta/2021-08-05 05:40//)

3. @000,用错误码,axios 非2xx的状态码都会 触发异步reject
(/@Ta/2021-08-05 08:25//)

4.

嗯,promise的reject用await等待之后会转换为异常,然后就会被下面的catch捕捉到。

(/@Ta/2021-08-05 09:02//)

5.
效率真快 小米MIX2s(白)
(/@Ta/2021-08-05 11:00//)

6.
网页插件优化了很多 小米MIX2s(白)
(/@Ta/2021-08-05 11:16//)

7.
(/@Ta/2021-08-05 12:41//)

8.

image.pngimage.png
一加8Pro

(/@Ta/2021-08-05 12:43//)

9. 很好用,强烈支持。
(/@Ta/2021-08-07 03:38//)

10.

测试IMG_20210806_192608.jpg
HUAWEI Mate 30 Pro 5G版

(/@Ta/2021-08-07 06:51//)

11.

p480015306 (1).jpg.gif
小米MIX2s(白)

(/@Ta/2021-08-07 09:52//)

12. 54909BC3-54B1-42AF-A70C-797DCD081845.jpeg
(/@Ta/2021-08-07 10:09//)

13.

视频链接

(/@Ta/2021-08-08 22:32//)

14.

音频链接


Redmi K30 Pro
(/@Ta/2021-08-09 02:05//)

15.
(/@Ta/2021-08-09 10:36//)

16. IMG_20201005_182109.jpg
(/@Ta/2021-08-10 10:20//)

17. 直传的endpoint可以公开,accesskey之内的放在哪儿的呢?如果前端能获取到岂不是能拿去干坏事?
(/@Ta/2021-08-10 10:49//)

18. 图片
Screenshot_2021-08-23-05-21-17-451_tv.danmaku.bili.jpg
(/@Ta/2021-08-23 05:39//)

19.

@唐志华https://hu60.cn/q.php/bbs.topic.101061.html

OSSAccessKeyId被公开,但是它本身就可以公开,只有它做不了任何事。OSSAccessKeySecret并不会被公开,公开的policy和signature仅提供了上传单个文件的权限(key、文件大小和文件md5被policy限制死,上传内容不相符的文件会失败),并且无法对已经上传的文件进行覆盖,因为如果文件已存在(fileExists: true),就不会给出policy和signature。

https://github.com/hu60t/hu60wap6/blob/08f420ab44115a7c8be69800009330cb9fcb7b84/src/class/CloudStorageAliyun.php#L36

(/@Ta/2021-08-23 10:56//)

下一页 1/2页,共24楼

回复需要登录

11月22日 13:49 星期五

本站由hu60wap6华为CPU驱动

备案号: 京ICP备18041936号-1