zoukankan      html  css  js  c++  java
  • spark-md5 C# JS 跳过浏览器限制上传超2G的文件

    写在前面:

                   项目需要  , 以前 做过一个单文件在2G以下  可以多个文件上传至服务器的功能,客户 不满足, 参考了很多前辈们的代码,在网上也找了不少 ,然后总结出来了一个 ,做一下总结。

    
    

    aspx:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link href="css/flieUpoload.css" rel="stylesheet" />
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <div class="container">
                    <input type="file" name="fileselect" id="fileselect" value="" multiple />
                    <input type="button" id="btnselect" value="选择上传的文件" />
                    <input type="button" id="btnupload" value="开始上传" />
                </div>
                 <table cellspacing="0" cellpadding="0" id="filelist">
                    <tr>
                        <td class="filename">文件名</td>
                        <td class="fileprogress">进度</td>
                        <td class="filestatus">状态</td>
                    </tr>
                    <tr id="trmsg">
                        <td colspan="3" id="tdmsg">请选择要上传的文件</td>
                    </tr>
                </table>
                <script src="js/jquery-1.10.2.min.js"></script>
                <script src="js/spark-md5.min.js"></script>
                <script src="js/FileUpoload.js"></script>
            </div>
        </form>
    </body>
    </html>
    View Code

    css:

    *{
        font-family: "微软雅黑";
        margin: 0;
        padding: 0;
    }
    
    .container {
        padding-top: 10px;
        padding-left: 10px;
    }
    
        .container input {
             120px;
            height: 30px;
            background-color: blue;
            color: white;
            border: 0;
            line-height: 30px;
            border-radius: 5px;
            margin-right: 5px;
            outline: none;
            cursor: pointer;
        }
    
    #filelist {
         800px;
        border: solid 1px #eee;
        border-collapse: collapse;
        margin: 10px;
    }
    
        #filelist td {
            border-bottom: solid 1px #eee;
            height: 30px;
            font-size: 12px;
            padding: 0 3px;
        }
    
    .filename {
         200px;
        text-align: center;
    }
    
    .filestatus {
         100px;
        text-align: center;
    }
    
    .fileprogress {
        text-align: center;
    }
    
    .domprogress {
         320px;
    }
    
    .domsize {
        display: block;
    }
    
    #tdmsg {
        text-align: center;
    }
    
    #fileselect {
        display: none;
    }
    
    span.domtime {
        display: block;
    }
    View Code

    js:

    $("#btnselect").click(function () {
        $("#fileselect").click();
    });
    $("#fileselect").change(function () {
        var files = this.files;
        if (files.length > 0) {
            $("#trmsg").remove();
            $(files).each(function (index, item) {
                console.log(index, item);
                var filesize = 0;
                if ((item.size / 1024 / 1024 / 1024) >= 1) {
                    filesize = (item.size / 1024 / 1024 / 1024).toFixed(2) + "GB"; // b=>kb=>mb=>gb
                } else if ((item.size / 1024 / 1024 / 1024) < 1 && (item.size / 1024 / 1024) >= 1) {
                    filesize = (item.size / 1024 / 1024).toFixed(2) + "MB";
                } else if ((item.size / 1024 / 1024) < 1 && (item.size / 1024) >= 1) {
                    filesize = (item.size / 1024).toFixed(2) + "KB";
                } else {
                    filesize = item.size + "B";
                }
    
                var htmlstr = '<tr><td>' + item.name + '</td><td><progress value="0" max="100" class="domprogress"></progress><span class="dompercent"> 0/' + filesize + '</span><span class="domtime">总共耗时:0 秒</span></td><td class="filestatus"><span class="domstatus">排队中</span></td></tr>';
                $("#filelist").append(htmlstr);
    
            });
    
        }
    
    });
    $.ajaxSetup({
        async: false
    });
    $("#btnupload").click(function () {
    
        var files = $("#fileselect")[0].files;
        $.ajaxSettings.async = false;
        $(files).each(function (index, item) {
            yyupload(files[index], $("span.domstatus").eq(index), $("span.dompercent").eq(index), $(".domprogress").eq(index), $("span.domtime").eq(index));
        });
        $.ajaxSettings.async = true;
    });
    
    //文件上传
    function yyupload(file, dommsg, dompercentmb, domprogress, domtime, fn) {
        var startTime = new Date();
        //获取文件的md5字符串,用于标识文件的唯一性。
        calculate(file);
        //获取文件的加密字符串
        function calculate(file) {
            var fileReader = new FileReader();
            var chunkSize = 1024 * 1024 * 5; //每次读取5MB
            var chunksCount = Math.ceil(file.size / chunkSize); //回大于参数x的最小整数 8=》8  8.4=》9  8.5=》9 -8.5=》-8
            var currentChunk = 0; //当前块的索引
            var spark = new SparkMD5();
            fileReader.onload = function (e) {
                //console.log((currentChunk + 1) + "/" + chunksCount)
                dommsg.text("正在检查文件: " + (currentChunk + 1) + "/" + chunksCount);
                spark.appendBinary(e.target.result); // 添加二进制字符串
                currentChunk++;
                if (currentChunk < chunksCount) {
                    loadNext();
                } else {
                    var md5value = spark.end();
                    //console.log("文件加密结束,密钥为:" + md5value);
                    checkfile(md5value, file); //检查服务器是否存在该文件,存在就从断点继续上传
                }
            };
    
            function loadNext() {
                var start = currentChunk * chunkSize; //计算读取开始位置
                var end = start + chunkSize >= file.size ? file.size : start + chunkSize; //计算读取结束位置
                fileReader.readAsText(file.slice(start, end)); //读取为二进制字符串readAsBinaryString
            };
            loadNext();
        }
    
        var repeatcount = 0;
        //检查文件是否已经存在
        function checkfile(md5value, file) {
            //var Id = GetQueryString("Id");
            $.ajaxSettings.async = false;
            var fd = new FormData();
            fd.append('rquesttype', "chekcfile");
            fd.append('filename', file.name);
            fd.append('md5value', md5value);
            //fd.append('type', GetQueryString("type"))
            //fd.append('Id', Id);
            var xhr = new XMLHttpRequest();
            xhr.open('post', 'FileUpoload.ashx', true);
            xhr.onreadystatechange = function (res) {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var jsonobj = JSON.parse(xhr.responseText); //可以将json字符串转换成json对象  //JSON.stringify(jsonobj); //可以将json对象转换成json对符串
                    console.log("继续上传的位置:" + jsonobj.startindex);
                    switch (jsonobj.flag) {
                        case "0":
                            doUpload(md5value, file, 0);
                            break;
                        case "1":
                            doUpload(md5value, file, parseInt(jsonobj.startindex));
                            break;
                        case "2":
    
                            secondUpload(file);
                            domtime.text("此文件已经存在,无法继续上传。");
                            break;
                    }
                    repeatcount = 0;
                } else if (xhr.status == 500) {
                    setTimeout(function () {
                        if (repeatcount < 3) {
                            checkfile(md5value, file);
                        }
                        repeatcount++;
                    }, 3000);
                }
            }
            //开始发送
            xhr.send(fd);
            $.ajaxSettings.async = true;
        }
    
        function secondUpload(file) {
            var timerange = (new Date().getTime() - startTime.getTime()) / 1000;
            domtime.text("耗时" + timerange + "");
            //显示结果进度
            var percent = 100;
            dommsg.text(percent.toFixed(2) + "%");
            domprogress.val(percent);
            var total = file.size;
            if (total > 1024 * 1024 * 1024) {
                dompercentmb.text((total / 1024 / 1024 / 1024).toFixed(2) + "GB/" + (total / 1024 / 1024 / 1024).toFixed(2) + "GB");
            } else if (total > 1024 * 1024) {
                dompercentmb.text((total / 1024 / 1024).toFixed(2) + "MB/" + (total / 1024 / 1024).toFixed(2) + "MB");
            } else if (total > 1024 && total < 1024 * 1024) {
                dompercentmb.text((total / 1024).toFixed(2) + "KB/" + (total / 1024).toFixed(2) + "KB");
            } else {
                dompercentmb.text((total).toFixed(2) + "B/" + (total).toFixed(2) + "B");
            }
    
        }
    
        //上传文件
        function doUpload(md5value, file, startindex) {
            var reader = new FileReader()
            var step = 1024 * 200;
            var cuLoaded = startindex;
            var total = file.size;
            //读取一段成功
            reader.onload = function (e) {
                //处理读取的结果
                var result = reader.result; //本次读取的数据
                var loaded = e.loaded; //本次读取的数据长度
                uploadFile(result, cuLoaded, function () { //将分段数据上传到服务器
                    cuLoaded += loaded; //如果没有读完,继续
                    var timerange = (new Date().getTime() - startTime.getTime()) / 1000;
                    if (total > 1024 * 1024 * 1024) {
                        dompercentmb.text((cuLoaded / 1024 / 1024 / 1024).toFixed(2) + "GB/" + (total / 1024 / 1024 / 1024).toFixed(2) + "GB");
                    } else if (total > 1024 * 1024) {
                        dompercentmb.text((cuLoaded / 1024 / 1024).toFixed(2) + "MB/" + (total / 1024 / 1024).toFixed(2) + "MB");
                    } else if (total > 1024 && total < 1024 * 1024) {
                        dompercentmb.text((cuLoaded / 1024).toFixed(2) + "KB/" + (total / 1024).toFixed(2) + "KB");
                    } else {
                        dompercentmb.text((cuLoaded).toFixed(2) + "B/" + (total).toFixed(2) + "B");
                    }
    
                    domtime.text("耗时" + timerange + "");
                    if (cuLoaded < total) {
                        readBlob(cuLoaded);
                    } else {
                        console.log('总共用时:' + timerange);
                        cuLoaded = total;
                        sendfinish(); //告知服务器上传完毕  
                        domtime.text("上传完成,总共耗时" + timerange + "");
                    }
                    //显示结果进度
                    var percent = (cuLoaded / total) * 100;
                    dommsg.text(percent.toFixed(2) + "%");
                    domprogress.val(percent);
                });
            }
            var k = 0;
            function sendfinish() {
                $.ajaxSettings.async = false;
                var fd = new FormData();
                fd.append('rquesttype', "finishupload");
                fd.append('filename', file.name);
                fd.append('md5value', md5value);
                fd.append('totalsize', file.size);
                fd.append('type', GetQueryString("type"));
                fd.append('id', GetQueryString("id"));
                //fd.append('type', GetQueryString("type"))
                var xhr = new XMLHttpRequest();
                xhr.open('post', 'FileUpoload.ashx', true);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        if (fn) {
                            fn(); //如果上传成功,继续上传下一个文件
                        }
                        k = 0;
                    } else if (xhr.status == 500) {
                        setTimeout(function () {
                            if (k < 3) {
                                sendfinish();
                                //上传完毕的前端处理
                            }
                            k++
                        }, 3000);
                    }
                }
                //开始发送
                xhr.send(fd);
                $.ajaxSettings.async = true;
            }
            var m = 0;
            //关键代码上传到服务器
            function uploadFile(result, startIndex, onSuccess) {
                var blob = new Blob([result]);
                //提交到服务器
                $.ajaxSettings.async = false;
                var fd = new FormData();
                fd.append('file', blob);
                fd.append('rquesttype', "uploadblob");
                fd.append('filename', file.name);
                fd.append('md5value', md5value);
                fd.append('loaded', startIndex);
    
                var xhr = new XMLHttpRequest();
                xhr.open('post', 'FileUpoload.ashx', true);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        m = 0;
                        if (onSuccess)
                            onSuccess();
                    } else if (xhr.status == 500) {
                        setTimeout(function () {
                            if (m < 3) {
                                containue();
                                m++;
                            }
                        }, 1000);
                    }
                }
                xhr.send(fd);
                $.ajaxSettings.async = true;
            }
    
            function readBlob(start) {
                var blob = file.slice(start, start + step);
                reader.readAsArrayBuffer(blob);
            }
            function containue() {
                readBlob(cuLoaded);
            }
            readBlob(cuLoaded);
        }
    
        function GetQueryString(name) {
    
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
    
            var r = window.location.search.substr(1).match(reg);
    
            if (r != null) return unescape(r[2]); return null;
    
        }
    }
    View Code

    ashx:

    using Microsoft.VisualBasic.Devices;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Web;
    using XLT.QC.Domain;
    using XLT.QC.Entity;
    
    namespace FTPupLoad.load
    {
        /// <summary>
        /// FileUpoload 的摘要说明
        /// </summary>
        public class FileUpoload : IHttpHandler
        {
    
            private string basefilename = HttpContext.Current.Server.MapPath("../doc/allFile/");
            private long totalCount = 0;
            public  HttpRequest reqs;
            public void ProcessRequest(HttpContext context)
            {
                HttpRequest req = context.Request;
    
                string rquesttype = req.Form["rquesttype"];
    
                var filename = req.Form["filename"];//文件的名称
    
                switch (rquesttype)
                {
                    case "chekcfile": chekcfile(req); break;
                    case "uploadblob": uploadblob(req); break;
                    case "finishupload":
                        reqs = req;
                        Task.Factory.StartNew(ThreadMethod);//解决线程并发
                        //finishupload(req);
                        break;
                }
    
    
    
            }
            public void ThreadMethod()
            {
                while (true)
                {
                    lock (typeof(FileUpoload))
                    {
    
                        finishupload(reqs);
                        Thread.Sleep(500);
                    }
                }
            }
            /// <summary>
            /// 结束文件上传,修改上传后的名称
            /// </summary>
            /// <param name="req"></param>
            public void finishupload(HttpRequest req)
            {
                string id = req.Form["id"];
                string type = req.Form["type"];
                //接收前端传递过来的参数
                var md5value = req.Form["md5value"];//文件md5加密的字符串
                var filename = req.Form["filename"];//文件的名称
                var totalsize = req.Form["totalsize"];//文件的总大小
    
                string fullname = basefilename + md5value + ".part";//上传的时候的名称
                string okname = basefilename + md5value + ".ok";
                var oldname = basefilename + filename;
                Computer MyComputer = new Computer();
                try
                {
                    //FileInfo okn = new FileInfo(okname);
                    //if (!okn.Exists)
                    //{
    
                    File.Create(okname);
                    //}
                    FileInfo fi = new FileInfo(oldname);
                    if (fi.Exists)
                    {
                        fi.Delete();
                    }
                    MyComputer.FileSystem.RenameFile(fullname, filename);
                }
                catch (Exception ex)
                {
    
                }
                finally
                {
    
                    ArtificialDataTitleDomain art = new ArtificialDataTitleDomain();
                    ArtificialDataTitleEntity Inspect = new ArtificialDataTitleEntity();
                    TestingMachineTitleDomain tmt = new TestingMachineTitleDomain();
                    TestingMachineTitleEntity Repair = new TestingMachineTitleEntity();
    
                    if (type == "Inspect")
                    {
                        Inspect = art.FindByID(id);
                        if (!string.IsNullOrWhiteSpace(Inspect.docUrl))
                        {
                            Inspect.docUrl = Inspect.docUrl + filename + ",";
                        }
                        else
                        {
                            Inspect.docUrl = "allFile*" + filename + ",";
                        }
    
                        art.Update(Inspect);
                    }
                    else if (type == "Repair")
                    {
                        Repair = tmt.FindByID(id);
                        if (!string.IsNullOrWhiteSpace(Repair.docUrl))
                        {
                            Repair.docUrl = Repair.docUrl + filename + ",";
                        }
                        else
                        {
                            Repair.docUrl = "allFile*" + filename + ",";
                        }
                        tmt.Update(Repair);
                    }
                    var str = string.Format("{{"data":"ok"}}");
                    HttpContext.Current.Response.Write(str);
                }
            }
    
    
            /// <summary>
            /// 处理文件分块上传的数据
            /// </summary>
            /// <param name="req"></param>
            public void uploadblob(HttpRequest req)
            {
                if (req.Files.Count <= 0)
                {
                    HttpContext.Current.Response.Write("获取服务器上传文件失败");
                    return;
                }
                HttpPostedFile _file = req.Files[0];
                //获取参数
                string filename = req.Form["filename"];
                string md5value = req.Form["md5value"];
    
                var tempfilename = md5value + ".part";
                //如果是int 类型当文件大的时候会出问题 最大也就是 1.9999999990686774G
    
                long loaded = Convert.ToInt64(req.Form["loaded"]);
                totalCount += loaded;
                string newname = basefilename + tempfilename;
                Stream stream = _file.InputStream;
                if (stream.Length <= 0)
                    throw new Exception("接收的数据不能为空");
                byte[] dataOne = new byte[stream.Length];
                stream.Read(dataOne, 0, dataOne.Length);
                FileStream fs;
                try
                {
                    fs = new FileStream(newname, FileMode.Append, FileAccess.Write, FileShare.Read, 1024);
                    fs.Write(dataOne, 0, dataOne.Length);
                    fs.Close();
                }
                catch (Exception ex)
                {
    
                }
                finally
                {
                    stream.Close();
                    //检查文件已经上传的大小是否等于文件的总大小
                }
                HttpContext.Current.Response.Write("分段数据保存成功");
            }
    
            /// <summary>
            /// 检查文件是否存在
            /// </summary>
            /// <param name="req"></param>
            public void chekcfile(HttpRequest req)
            {
                var md5value = req.Form["md5value"];//得到前端传递过来的文件的mdf字符串
                var path_ok = basefilename + md5value + ".ok";
                var path_part = basefilename + md5value + ".part";
                int flag = 0;
                string json = string.Empty;
                if (File.Exists(path_ok))//传完了
                {
    
                    flag = 2;
                    json = string.Format("{{"flag":"{0}"}}", flag);
                }
                else if (File.Exists(path_part))//传了一部分
                {
                    flag = 1;
                    var startindex = new FileInfo(path_part).Length.ToString();
                    json = string.Format("{{"flag":"{0}","startindex":"{1}"}}", flag, startindex);
                }
                else//新文件
                {
                    flag = 0;
                    json = string.Format("{{"flag":"{0}","startindex":"0"}}", flag);
                }
                HttpContext.Current.Response.Write(json);
            }
    
    
            public bool IsReusable
            {
                get
                {
                    return false;
                }
            }
        }
    }
    View Code
  • 相关阅读:
    三元表达式 列表和字典推导式 函数对象 名称空间 作用域 global和nonlocal 函数装饰器 枚举对象
    函数参数 打散机制 字符串比较 返回值
    函数简介
    三种字符串的介绍 文件的读写
    字符编码
    数据类型及其常用方法 数据类型转换 可变与不可变 值拷贝与深浅拷贝
    流程控制 while和for循环
    变量命名规范 常量 输入和输出 注释 数据类型 运算符 逻辑运算符
    语言分类 编译型和解释型语言分析 环境变量 代码执行的方式 pip介绍 变量
    Python django tests
  • 原文地址:https://www.cnblogs.com/niesiao/p/9540371.html
Copyright © 2011-2022 走看看