免Flash文件上传

无需调用Flash,从课程平台上传附件,不必为了传作业多装一个浏览器!

目前为 2021-09-12 提交的版本。查看 最新版本

// ==UserScript==
// @name              免Flash文件上传
// @name:en           Upload without Flash
// @namespace         https://gf.qytechs.cn/zh-CN/users/605474
// @version           1.1
// @description       无需调用Flash,从课程平台上传附件,不必为了传作业多装一个浏览器!
// @description:en    No need to call Flash, upload accessories from the course platform, do not have to make multiple browsers for the homework!
// @author            Ziu
// @match             *://cc.bjtu.edu.cn:81/*
// @match             *://cc.bjtu.edu.cn:81/meol/common/hw/student/write.jsp?hwtid=*
// @icon              https://gitee.com/ziuc/utool-filebed/raw/master/20210514-231824-0795.png
// @require           https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js
// @require           https://cdn.bootcdn.net/ajax/libs/jquery/1.7.2/jquery.min.js
// @grant             none
// @license           MIT
// ==/UserScript==

(function() {
    'use strict';
    let index = 0;
    let isAbort = 0;
    let oloaded = 0;
    let ot = 0;
    let frontTag = "<li><a id='add_button' title='上传作业' onclick=location='http://cc.bjtu.edu.cn:81/meol/common/hw/student/hwtask.jsp?tagbug=client&strStyle=new06'><span>上传作业</span></a></li>";
    let uploadBox = '<tr><td><div style="font-size: 14px; width: 550px; margin:0 auto; margin-top: 10px;"><div id="inputDiv" title="点击选择文件上传" style="height: 200px; width: 560px; cursor:pointer; border: 3px dashed; border-radius:10px; border-color: #82b900; background: #c6f062;"><div id="inputArea"><div id="textShow" style="margin-top: 80px; font-size: 20px; color: #5c6b77; text-align: center;"><p>📁文件上传📄</p><p style="font-size: 15px">(文件最大上传1024M)</p></div><input id="currentFile" type="file" multiple="multiple" style="display:none;" </input></div></div><div id="filenames" style="margin-top: 10px; margin-bottom: 10px; background-color: #e7e8e0;"></div><div id="buttonDiv" style="margin-top: 10px; margin-bottom: 10px; text-align: center"></div></div></td></tr>'
    let uploadBtn = '<a id="uploadTrigger" title="上传" style="cursor:pointer; padding-top: 2.5px; padding-bottom: 2.5px; padding-right: 5px; padding-left: 5px; background-color: #c6f062; border: 2px solid;">上传</a>&nbsp&nbsp';
    let emptyBtn = '<a id="emptyTrigger" title="清空" style="cursor:pointer; padding-top: 2.5px; padding-bottom: 2.5px; padding-right: 5px; padding-left: 5px; background-color: #c6f062; border: 2px solid;">清空</a>';

    // 外部DOM操作
    $('#tmenu').append(frontTag);
    $('.infotable>tbody>tr:contains("请输入你的答案")').after(uploadBox);

    // 动效
    $('#inputDiv').mouseenter(function (){$('#inputDiv').css('background-color','#87bd04');$('#textShow').css('color','#e7e8e0')});
    $('#inputDiv').mouseleave(function (){$('#inputDiv').css('background-color','#c6f062');$('#textShow').css('color','#5c6b77')});

    // 文件选择前事件监听
    $('#inputDiv').click(function (){$('#currentFile').trigger('click');});
    $('#currentFile').change(fileChangedByInput);

    function fileChangedByInput(){
        let filelist = $('#currentFile')[0].files;
        // 缓存区展示
        $('#inputDiv').hide(); // 隐藏上传框
        $('#filenames, #buttonDiv').empty(); // 先清空 再插入
        let sizeType = getSizeType(filelist);
        for(let i=0;i<filelist.length;i++){
            let item = {};
            item.file = filelist[i];
            item.sizeType = sizeType[i];
            let fileObject = '<div class="fileObjects" id="fileTh'+i+'"style="cursor:default; margin-top: 10px; background-color: #e7e8e0;background-image: url(http://cc.bjtu.edu.cn:81/meol/styles/newstyle/course/new06/body_bg.jpg); background-repeat:no-repeat; background-size: 0%;"><a class="fileindex" id="fileindex'+i+'" title="[文件]" style="margin-left: 5px;">📄</a><a class="filename" title="'+item.file.name+'">&nbsp&nbsp|&nbsp&nbsp'+item.file.name+' ('+item.sizeType.size+item.sizeType.type+')'+'</a><a class="uploadSpeed" id="speedTh'+i+'" title="上传速度">&nbsp | &nbsp⚡</a><a class="timeRemain" id="timeRemainTh'+i+'"></a></div>';
            $('#filenames').append(fileObject);
        }

        // 文件选择后外部DOM插入
        $('#buttonDiv').append(uploadBtn);
        $('#buttonDiv').append(emptyBtn);

        // 文件选择后事件监听
        $('#emptyTrigger').click(function (){$('#currentFile').val('');$('#filenames, #buttonDiv').empty();$('#inputDiv').show();isAbort=1;});
        $('#uploadTrigger').click(function (){
            // 处理文件缓存区
            $('#uploadTrigger').hide();
            $('#uploadTrigger').css('cursor','not-allowed');
            isAbort = 0; // 按上传之前按过清空,将isAbort置回0
            sendFileMsg();
            function sendFileMsg(){
                if(index >= filelist.length){
                    // 递归结束
                    $('#currentFile').val(''); // <input>文件清空
                    $('#emptyTrigger').css('cursor','pointer');
                    index = 0; // 递归条件置零
                    return // 结束递归
                }

                let formData = new FormData();
                formData.append('Filename', filelist[index].name);
                formData.append('Filedata', filelist[index]);

                let xReq = new XMLHttpRequest();
                xReq.open('POST','http://cc.bjtu.edu.cn:81/meol/servlet/SerUpload');
                xReq.addEventListener("load", onSuccess);
                xReq.addEventListener("error", onError);
                xReq.upload.onloadstart = onStart;
                xReq.upload.onprogress = onProgress;
                xReq.upload.onabort = onAbort;
                xReq.send(formData);

                function onStart(){
                    ot = new Date().getTime(); // 设置上传开始时间,用以计算时间速度
                    oloaded = 0; // 设置上传开始时,已上传的文件大小为0
                }

                function onProgress(evt){
                    if(isAbort==1){
                        xReq.abort(); // 上传过程中随时检查,终止请求
                    }
                    // 进度计算
                    let percentage;
                    percentage = (evt.loaded * 100 / evt.total).toFixed(0);

                    // 速度计算
                    let nt = new Date().getTime(); // 获取当前时间
                    let perTime = (nt-ot)/1000; // 计算出上次调用该方法时到现在的时间差,单位为s
                    ot = new Date().getTime(); //重新赋值,用以下次计算
                    let perLoad = evt.loaded - oloaded; // 计算该分段上传的文件大小,单位b
                    oloaded = evt.loaded; // 重新赋值,用以下次计算
                    let speed = perLoad/perTime; // 单位 B/s
                    let bspeed = speed;
                    let Sunits = 'B/s';
                    if(speed/1024>1){
                        speed = speed/1024;
                        Sunits = 'KB/s'
                    }
                    if(speed/1024>1){
                        speed = speed/1024;
                        Sunits = 'MB/s';
                    }
                    speed = speed.toFixed(1);

                    // 时间计算 文件>100MB触发
                    if(evt.total>104857600){
                        let restTime = ((evt.total-evt.loaded)/bspeed).toFixed(0);
                        // 更新文件缓存区
                        $('#timeRemainTh'+index).html('&nbsp | &nbsp🕒'+restTime+'秒');
                    }

                    // 更新文件缓存区
                    $('#fileTh'+index).css('background-size',percentage+'%');
                    $('#speedTh'+index).html('&nbsp | &nbsp⚡'+speed+Sunits);
                }

                function onAbort(){
                    isAbort = 0; // 终止条件置零
                    index = 0; // 请求终止后index也必须归零,因为中止未完成递归,若中止文件index>0则第二次上传请求无法发起
                }

                function onSuccess(){
                    // 插入编辑器操作
                    let myiframe = document.getElementsByTagName('iframe')[1].contentDocument;
                    let textArea = myiframe.getElementsByClassName('cke_show_borders');
                    let constructor = '<p><a data-cke-saved-href="/meol/'+this.responseText+'" href="/meol/'+this.responseText+'">'+filelist[index].name+'</a></p>'
                    $(textArea).append(constructor);

                    // 处理缓存区操作
                    $('#speedTh'+index).html('&nbsp | &nbsp✅');
                    $('#speedTh'+index).attr('title','[已上传]');
                    $('#timeRemainTh'+index).remove();
                    $('#fileTh'+index).css('background','#c6f062');

                    // 递归操作
                    index++;
                    sendFileMsg();
                    // alert('上传成功');
                }
                function onError(){
                    alert('上传失败');
                }
            }
        })
    }

    function getSizeType(filelist){
        let RtnsizeType = [];
        for(let item of filelist){
            let sizeTypeTMP = {};
            if(item.size<1024){
                sizeTypeTMP.size = (item.size).toFixed(2);
                sizeTypeTMP.type = 'B';
            }
            else if(item.size>1024&&item.size<1048576){
                sizeTypeTMP.size = (item.size/1024).toFixed(2);
                sizeTypeTMP.type = 'KB';
            }
            else if(item.size>1048576&&item.size<1073741824){
                sizeTypeTMP.size = (item.size/1048576).toFixed(2);
                sizeTypeTMP.type = 'MB';
            }
            else if(item.size>1073741824){
                alert('你选择了大于1GB的文件,服务器存储资源有限,建议选择其他传输方式。');
                sizeTypeTMP.size = (item.size/1073741824).toFixed(2);
                sizeTypeTMP.type = 'GB';
            }
            RtnsizeType.push(sizeTypeTMP);
        }
        return RtnsizeType;
    }

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址