• 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
  • 相关阅读:
    ASP.Net 2.0窗体身份验证机制详解(FormsAuthentication) (转载)
    获取页面得所有控件
    标题: 如何断开与另一台机器的连接(更换用户名和口令)
    C#数据类型及范围
    常用数学符号读法大全
    理解偏序关系
    理解全序关系
    理解拟序关系
    《离散数学》双语专业词汇表 名词术语中英文索引
    ORL人脸库
  • 原文地址:https://www.cnblogs.com/niesiao/p/9540371.html
Copyright © 2020-2023  润新知