文件上传的几个例子

项目中用到的几个文件上传的例子,记录下,免得以后重复查找。

1、html5文件上传

以前上传文件需要提交Form表单。
HTML5方式上传文件,可以通过使用FormData类模拟Form表单提交,从而实现无刷新上传文件。

假设有一个文件选择框

<input id="chooseImage" type="file" style="display: none">

可以在html中另外写一个dom来触发文件选择,或者直接使用文件选择也可以(丑一点)

  
<style>
    .upload_img {
        width: 80px;
        height: 80px;
        background-color: #fff;
        color: green;
        border: 1px solid green;
        border-radius: 5px;
        text-align: center;
        line-height: 80px;
        font-size: 40px;
        background-position: center;
        background-size: contain;
        cursor: pointer;
    }
</style>

<div class="form-group cell_upload">
                    <label class="col-sm-4 control-label no-padding-right" for="pname"><span class="lbl-warning">*</span> 转让文件 </label>
                    <div class="col-sm-4">
                        <div class="upload_img" style="background-image: url(&quot;&quot;);">+</div>   
                    </div>
                    <div class="col-sm-4">
                        <div class="upload_ready"></div>
                    </div>
                </div>

$(function () {
        $('.cell_upload .upload_img').click(function () {
            $('#chooseImage').click();//激活图片上传
        });      
    })
View Code

选择XMLHttpRequest方式上传(有进度事件)

 //图片上传
    $("#chooseImage").change(function () {
        var file = $(this)[0].files[0];//获取files对象

        //禁用提交按钮
        $('.btn-primary-transfer').attr('disabled', true);
        $('.btn-primary-transfer').css('background-color', '#ccc');
        //显示进度条
        $('.cell_upload').after($('.progressbar'));
        $('.progressbar #sliderTrack').width('0%');
        $('.progressbar #sliderHandler').css('left', '0%');
        $('.progressbar #sliderValue').html('0%');
        $('.progressbar').show();
   
        var files = document.getElementById('chooseImage').files; //files是文件选择框选择的文件对象数组

        if (files.length == 0) return;

        var form = new FormData(),
            url = '/DC/File/patent_transferUpload', //服务器上传地址
            file = files[0];
        form.append('file', file);

        var xhr = new XMLHttpRequest();
        xhr.open("post", url, true);

        //上传进度事件
        xhr.upload.addEventListener("progress", function (progress) {
            if (progress.lengthComputable) {
                //上传进度
                var prog = parseInt(progress.loaded / progress.total * 100);
                $('.progressbar #sliderTrack').width(prog + '%');
                $('.progressbar #sliderHandler').css('left', prog + '%');
                $('.progressbar #sliderValue').html(prog + '%');
            }
        }, false);

        xhr.addEventListener("readystatechange", function () {
            var result = xhr;
            if (result.status != 200) { //error
                console.log('上传失败', result.status, result.statusText, result.response);
            }
            else if (result.readyState == 4) { //finished
                console.log('上传成功', result);
                $('#btnSubmit').removeAttr('disabled');
                $('#btnSubmit').css('background-color', '#1AAD19');
                $('.progressbar').slideUp();

                let resp = JSON.parse(result.response);
              
                if (resp.state) {
                    $('#filepath').val(resp.filepath);
                    $('#filename').val(resp.filename);
                    let vfile = `<a href="${resp.filePath}" download="${resp.fileName}" target="_blank">${resp.fileName}</a>`;
                    $('.cell_upload .upload_ready').html(vfile);
                    $('.cell_upload .upload_img').html('✔'); 
                 
                }
            }
        });
        xhr.send(form); //开始上传
    
    })
View Code
@*图片上传工具*@
<input id="chooseImage" type="file" style="display: none">

@*进度条*@
<div class="weui-cell progressbar">
    @*<div class="weui-cell__hd"><label class="weui-label">进度</label></div>*@
    <div class="weui-cell__bd">
        <div class="weui-slider-box">
            <div class="weui-slider">
                <div id="sliderInner" class="weui-slider__inner" style="background-color: #aaa;">
                    <div id="sliderTrack" style=" 0%;" class="weui-slider__track"></div>
                    <div id="sliderHandler" style="left: 0%;" class="weui-slider__handler"></div>
                </div>
            </div>
            <div id="sliderValue" class="weui-slider-box__value">50</div>
        </div>
    </div>

</div>
进度条html

附加:另外一种网友提供的方式,自己木有使用

var form = new FormData(),
    url = 'http://.......', //服务器上传地址
    file = files[0];
form.append('file', file);
 
fetch(url, {
    method: 'POST',
    body: form
}).then(function(response) {
    if (response.status >= 200 && response.status < 300) {
        return response;
    } 
    else {
        var error = new Error(response.statusText);
        error.response = response;
        throw error;
    }
}).then(function(resp) {
    return resp.json();
}).then(function(respData) {
    console.log('文件上传成功', respData);
}).catch(function(e) {
    console.log('文件上传失败', e);
});

--------------------- 
作者:神秘_博士 
来源:CSDN 
原文:https://blog.csdn.net/lovelyelfpop/article/details/71421123 
版权声明:本文为博主原创文章,转载请附上博文链接!
View Code

后台接收程序(项目使用的是.net mvc)

   public JsonResult patent_transferUpload()
        {
            string physicalFolderPath = string.Empty;//物理文件夹路径
            HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;

            if (string.IsNullOrEmpty(this.demandFolderPath))
            {
                // physicalFolderPath = Server.MapPath(@"FilesDemandFiles");
                physicalFolderPath = "/Files/patent_transfer";
            }
            else
            {
                physicalFolderPath = this.demandFolderPath;
            }

            return Upload(hfc, physicalFolderPath, "");
        }


  /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="hfc">文件信息</param>
        /// <param name="physicalFolderPath">物理文件存储文件夹绝对路径</param>
        /// <returns></returns>
        private JsonResult Upload(HttpFileCollection hfc, string physicalFolderPath,string guid)
        {
            try
            {
                string msg = "位置错误!";
                string physicalFullPath = string.Empty;
                string fileName = string.Empty;
                bool isSuccess = false;
                var files = Request.Files;
                if (guid == "") {
                    guid = Guid.NewGuid().ToString();
                }
               
                if (hfc != null && hfc.Count > 0)
                {
                    try
                    {
                        fileName = hfc[0].FileName;
                        if (!string.IsNullOrEmpty(fileName))
                        {
                          
                            string save_dir= Server.MapPath(physicalFolderPath);
                          
                            if (!Directory.Exists(save_dir))
                            {
                                Directory.CreateDirectory(save_dir);
                            }
                            physicalFullPath = physicalFolderPath + "/" + guid + Path.GetExtension(fileName);
                            string savepath = Server.MapPath(physicalFullPath) ;
                            hfc[0].SaveAs(savepath);
                            isSuccess = true;
                            msg = "上传成功!";
                        }
                        else
                        {
                            msg = "未识别任何有效文件!";
                        }

                    }
                    catch (Exception e)
                    {
                        msg = e.Message;
                    }
                }

                return Json(new { state = isSuccess, message = msg,guid= guid, fileName = fileName, filePath = physicalFullPath }, JsonRequestBehavior.AllowGet);
            }
            catch {
                return Json(new { state = false, message = "上传文件失败!" }, JsonRequestBehavior.AllowGet);
            }
        }
View Code

引用:

https://blog.csdn.net/lovelyelfpop/article/details/71421123

*************************************************************** 华丽丽的分割线 ***************************************************************

2 移动端的图片压缩上传(使用二进制数据流)

这是一个在微信公众号开发中用到的图片上传

同1,在html中添加一个文件上传的控件

<input id="chooseImage" type="file" style="display: none">

然后在写一个控件来触发文件上传,同时为上传添加进度条显示.progressbar

 <style>

        .upload_img {
            width: 80px;
            height: 80px;
            background-color: #fff;
            color: green;
            border:1px solid green;
            border-radius: 5px;
            text-align: center;
            line-height: 80px;
            font-size: 40px;
            background-position:center;
            background-size:contain;
        }

        .upload_delete {
            display:none;
            width: 30px;
            height: 30px;
            background-color: orangered;
            color: #fff;
            border-radius: 50%;
            text-align: center;
            line-height: 30px;
            font-size: 24px;
            margin-left: 20px;
        }
    </style>




<div >
    <div class="weui-cell__hd"><label class="weui-label"></label></div>
    <div class="weui-cell__bd cell_upload box-space-between" tag="2e89acb0-b36e-4934-9c31-f718aea815f9">
        <div tag="" class="upload_img" style="background-image: url(&quot;&quot;);">+</div>
        <div tag="" class="upload_delete" style="display: none;">-</div>        
        <input class="upload_save" id="" type="text" style="display:none;">
    </div>
</div>




   @*图片上传工具*@
    <input id="chooseImage" type="file" style="display: none">

    @*进度条*@
    <div class="weui-cell progressbar">
        @*<div class="weui-cell__hd"><label class="weui-label">进度</label></div>*@
        <div class="weui-cell__bd">
            <div class="weui-slider-box">
                <div class="weui-slider">
                    <div id="sliderInner" class="weui-slider__inner" style="background-color: #aaa;">
                        <div id="sliderTrack" style=" 0%;" class="weui-slider__track"></div>
                        <div id="sliderHandler" style="left: 0%;" class="weui-slider__handler"></div>
                    </div>
                </div>
                <div id="sliderValue" class="weui-slider-box__value">50</div>
            </div>
        </div>

    </div>
View Code

上传限制了图片的类型和大小

   //图片上传
        $("#chooseImage").change(function () {
            var file = $(this)[0].files[0];//获取files对象

            var rFilter = /^(image/jpeg|image/png)$/i; // 检查图片格式
            if (!rFilter.test(file.type)) {
                wxAlert.showMsg('只可以上传.jpg/.jpeg/.png格式的图片!');
                return false;
            }

            if (file.size > 5000000) {
                wxAlert.showMsg('上传图片最大为5M,请重新上传!');
                return false;
            }
            //禁用提交按钮
            $('#btnSubmit').attr('disabled', true);
            $('#btnSubmit').css('background-color', '#ccc');
            //显示进度条
            $('.cell_upload').parent().after($('.progressbar'));
            $('.progressbar #sliderTrack').width('0%');
            $('.progressbar #sliderHandler').css('left', '0%');
            $('.progressbar #sliderValue').html('0%');
            $('.progressbar').show();

            //0.5为当前压缩比
            var ratio = 1;
            if (file.size > 500000 && file.size <= 1000000) {
                ratio = 0.8;//0.5-1M压缩比
            }
            else if (file.size > 1000000 && file.size <= 2000000) {
                ratio = 0.7;//1-2M压缩比
            } else if (file.size > 2000000 && file.size <= 5000000) {
                ratio = 0.5;//2-5M压缩比
            } else if (file.size > 5000000 && file.size <= 10000000) {
                ratio = 0.4;//5-10M压缩比
            }

            file_compress(file, ratio);

        })

        //压缩文件并上传
        function file_compress(file, ratio) {
            $.compress(file, ratio).then((url) => {
                $('.upload_img').css({ "background-image": "url(" + url + ")" });
                /*----------------上传到服务器-----------------*/
                var posturl = '/wechatPage/health_record/health_recordFile';
                var filename = hr_type_selected + '_' + health_record_id + '_' + templateID_active;//文件名定义为typeID+’_’+hrID+’_’+templateID.jpg
                var para = { imgbase: url, filename: filename };

                $.ajax({
                    type: "POST",
                    url: posturl,
                    data: para, //这里上传的数据使用了formData 对象
                    xhr: function () {
                        var xhr = $.ajaxSettings.xhr();
                        if (xhr.upload) {
                            xhr.upload.onprogress = function (progress) {
                                if (progress.lengthComputable) {
                                    //上传进度
                                    var prog = parseInt(progress.loaded / progress.total * 100);
                                    $('.progressbar #sliderTrack').width(prog + '%');
                                    $('.progressbar #sliderHandler').css('left', prog + '%');
                                    $('.progressbar #sliderValue').html(prog + '%');
                                }
                            };
                            xhr.upload.onloadstart = function () {
                                console.log('started...');
                            };
                        }
                        return xhr;
                    }
                }).done(function (resp) {
                    //上传完成
                    $('#btnSubmit').removeAttr('disabled');
                    $('#btnSubmit').css('background-color', '#1AAD19');
                    $('.progressbar').slideUp();
                    if (resp.state) {
         //do something
                    }
                }).fail(function (err) {
                    alert('无法连接服务器!')
                });

            })
        }
    
View Code

压缩处理图片(需将此compress.js文件引用到html中)

compress.js 先创建了一块画布canvas,然后根据需要压缩的程度,使用canvas进行画图,然后再将画好的压缩过的图片转化为数据流返回,

resolve关键字可理解为Promise的正确执行后的返回值。

Promise的then关键字即是接收resolve传回的参数

(function ($) {
    $.extend({
        //压缩图片,参数1:file对象,参数2:压缩比例
        compress(file, scale) {
            return new Promise(function (resolve, reject) {


                let _scale = scale || 1;
                let cvs = document.createElement('canvas');
                let ctx = cvs.getContext('2d');
                let img = new window.Image();
                let imgType = file.type;
                img.src = URL.createObjectURL(file);

                img.onload = function () {

                    cvs.width = img.width * _scale;
                    cvs.height = img.height * _scale;

                    EXIF.getData(img, function () {

                        EXIF.getAllTags(this);

                        var orient = EXIF.getTag(this, 'Orientation');
                        //alert('orient:' + orient);

                        switch (orient) {
                            case 3:
                                ctx.rotate(180 * Math.PI / 180);
                                ctx.drawImage(img, -cvs.width, -cvs.height, cvs.width, cvs.height);
                                break;
                            case 6:
                                cvs.width = img.height * _scale;
                                cvs.height = img.width * _scale;
                                ctx.rotate(90 * Math.PI / 180);
                                ctx.drawImage(img, 0, -cvs.width, cvs.height, cvs.width);

                                break;
                            case 8:
                                ctx.rotate(270 * Math.PI / 180);
                                ctx.drawImage(img, -cvs.height, 0, cvs.height, cvs.width);
                                break;
                            case 2:
                                ctx.translate(cvs.width, 0);
                                ctx.scale(-1, 1);
                                ctx.drawImage(img, 0, 0, cvs.width, cvs.height);
                                break;
                            case 4:
                                ctx.translate(cvs.width, 0);
                                ctx.scale(-1, 1);
                                ctx.rotate(180 * Math.PI / 180);
                                ctx.drawImage(img, -cvs.width, -cvs.height, cvs.width, cvs.height);
                                break;
                            case 5:
                                ctx.translate(cvs.width, 0);
                                ctx.scale(-1, 1);
                                ctx.rotate(90 * Math.PI / 180);
                                ctx.drawImage(img, 0, -cvs.width, cvs.height, cvs.width);
                                break;
                            case 7:
                                ctx.translate(cvs.width, 0);
                                ctx.scale(-1, 1);
                                ctx.rotate(270 * Math.PI / 180);
                                ctx.drawImage(img, -cvs.height, 0, cvs.height, cvs.width);
                                break;
                            default:
                                ctx.drawImage(img, 0, 0, cvs.width, cvs.height);
                        }
                        resolve(cvs.toDataURL(imgType));

                    });

                }

            });
        }
    
    });
    
})(jQuery)
compress.js

期间遇到iphone手机直接拍摄图片后上传,图片反转90度的问题,在compress.js 获取了文件的Orientation属性

  var orient = EXIF.getTag(this, 'Orientation');

可以根据图片的翻转类型对图片的反转度进行调整。

后台接收程序

 /// <summary>
        /// 上传健康档案文件
        /// </summary>
        /// <param name="imgbase">图片数据流</param>
        /// <param name="filename">保存的图片名</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult health_recordFile(string imgbase, string filename)
        {
            try
            {
                //保存目录
                string dir = "/Files/health_record";
                //站点文件目录
                string fileDir = Server.MapPath("~" + dir);
                //保存文件所在站点位置
                string filePath = Path.Combine(fileDir, filename);

                if (!System.IO.Directory.Exists(fileDir))
                    System.IO.Directory.CreateDirectory(fileDir);

                //将Base64String转为图片并保存
                // byte[] arr2 = Convert.FromBase64String(imgbase);
                byte[] arr2 = Convert.FromBase64String(imgbase.Substring(imgbase.IndexOf(',') + 1));
                using (MemoryStream ms2 = new MemoryStream(arr2))
                {
                    System.Drawing.Bitmap bmp2 = new System.Drawing.Bitmap(ms2);
                    bmp2.Save(filePath + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                    bmp2.Dispose();
                }

                var msg = new { state = true, msg = "上传图片成功!", imgsrc = dir + "/" + filename + "" + ".jpg" };
                return Json(msg);
            }
            catch
            {
                var msg = new { state = false, msg = "上传图片失败!", imgsrc = "" };
                return Json(msg);
            }
        }
View Code

附:js中使用了Promise函数的简介说明

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h4>Promise:把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数</h4>
<h5>resolve:将Promise的状态置为fullfiled,可理解为成功回调</h5>
<h5>reject:将Promise的状态置为rejected,可理解为失败回调</h5>
<h5>then:then接收一个参数,是函数,并且会拿到我们在runAsync中调用resolve时传的的参数</h5>
<h5>catch:catch接收一个参数,是函数,并且会拿到我们在runAsync中调用reject时传的的参数</h5>
<h5>all:提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调「谁跑的慢,以谁为准执行回调」</h5>
<pre>all的使用场景1:一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。</pre>
<pre>all的使用场景2:在较复杂的页面,等所有的异步加载全部完成后,再渲染页面。</pre>
<h5>race:同all一样提供并行操作的能力,区别是race执行标准是:[谁跑的快,以谁为准执行回调]</h5>
<pre>race使用场景:用race给某个异步请求设置超时时间,并且在超时后执行相应的操作(比如请求图片时设置超时时间)</pre>
<script type="text/javascript" src="../../script/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    $(function () {
        fun_01();

        fun_02();

        fun_03();
    })

    let fun_01=()=>{
        console.log('---------- Promise01 ----------');
       new Promise(test).then(function (result) {
           console.log('Success:'+result);
       }).catch(function (result) {
           console.log('Fail:'+result);
       })
    };

    function  test(resolve,reject) {
        let timeout=Math.random()*2;
        console.log('set timeout to:'+timeout+' seconds');
        setTimeout(function () {
            if(timeout<1){
                console.log('call resolve()...');
                resolve('200 OK');
            }else{
                console.log('call reject()...');
                reject('timeout in '+timeout+' seconds');
            }
        },timeout*1000);
    }


    let fun_02=()=>{
        console.log('---------- Promise02 ----------');
        runAsync().then(function (data) {
            console.log(data);
        });

        runAsync1().then(function (data) {
            console.log(data);
            return runAsync2();
        }).then(function (data) {
            console.log(data);
            return runAsync3();
        });

        setTimeout(runAll,5*1000);

    };

    function  runAll() {
        console.log('----------Promise.all----------');
        //Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调
        Promise.all([runAsync1(),runAsync2(),runAsync3()]).then(function (result) {
            console.log(result);
        })
    }

    function runAsync() {
        let p=new Promise(function (resolve,reject) {
            setTimeout(function () {
                console.log('timeout done!');
                resolve(' anythind you want');
            })
        })
        return p;
    }

    function runAsync1(){
        var p = new Promise(function(resolve, reject){
            //做一些异步操作
            setTimeout(function(){
                console.log('异步任务1执行完成');
                resolve('随便什么数据1');
            }, 1000);
        });
        return p;
    }
    function runAsync2(){
        var p = new Promise(function(resolve, reject){
            //做一些异步操作
            setTimeout(function(){
                console.log('异步任务2执行完成');
                resolve('随便什么数据2');
            }, 1000);
        });
        return p;
    }
    function runAsync3(){

        var p = new Promise(function(resolve, reject){
            //做一些异步操作
            setTimeout(function(){
                console.log('异步任务3执行完成');
                resolve('随便什么数据3');
            }, 1000);
        });
        return p;
    }

    let fun_03=()=>{
        console.log('---------- Promise03 ----------');
        Promise
            .race([requestImg(), timeout()])
            .then(function(results){
                console.log(results);
            })
            .catch(function(reason){
                console.log(reason);
            });
    };

    //请求某个图片资源
    function requestImg(){
        var p = new Promise(function(resolve, reject){
            var img = new Image();
            img.onload = function(){
                resolve(img);
            }
            img.src = 'xxxxxx';
        });
        return p;
    }

    //延时函数,用于给请求计时
    function timeout(){
        var p = new Promise(function(resolve, reject){
            setTimeout(function(){
                reject('图片请求超时');
            }, 5000);
        });
        return p;
    }

</script>
</body>
</html>
Promise

*************************************************************** 华丽丽的分割线 ***************************************************************

3.dropzone文件上传

官网:https://www.dropzonejs.com/

中文文档:http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/#configuration

个人觉得比较好的一个上传工具,常用的配置项和事件都很清楚,自带多文件上传和进度条,很赞。

不好的地方时,每个页面只能初始化一个dropzone,如遇到页面嵌套的dom也需要上传文件的情况就处理不了了,目前木有解决,官方也木有闻文档说明。

下面是需要引用的css文件(由于在上传单文件的时候,dropzone原来的上传框页面尺寸太大,我对css又做了一点调整,使其适合单独放在页面的dom中,所以自己记录下)

当然原始文件官网都可以下载到

/*
 * The MIT License
 * Copyright (c) 2012 Matias Meno <m@tias.me>
 */
@-webkit-keyframes passing-through {
  0% {
    opacity: 0;
    -webkit-transform: translateY(40px);
    -moz-transform: translateY(40px);
    -ms-transform: translateY(40px);
    -o-transform: translateY(40px);
    transform: translateY(40px); }
  30%, 70% {
    opacity: 1;
    -webkit-transform: translateY(0px);
    -moz-transform: translateY(0px);
    -ms-transform: translateY(0px);
    -o-transform: translateY(0px);
    transform: translateY(0px); }
  100% {
    opacity: 0;
    -webkit-transform: translateY(-40px);
    -moz-transform: translateY(-40px);
    -ms-transform: translateY(-40px);
    -o-transform: translateY(-40px);
    transform: translateY(-40px); } }
@-moz-keyframes passing-through {
  0% {
    opacity: 0;
    -webkit-transform: translateY(40px);
    -moz-transform: translateY(40px);
    -ms-transform: translateY(40px);
    -o-transform: translateY(40px);
    transform: translateY(40px); }
  30%, 70% {
    opacity: 1;
    -webkit-transform: translateY(0px);
    -moz-transform: translateY(0px);
    -ms-transform: translateY(0px);
    -o-transform: translateY(0px);
    transform: translateY(0px); }
  100% {
    opacity: 0;
    -webkit-transform: translateY(-40px);
    -moz-transform: translateY(-40px);
    -ms-transform: translateY(-40px);
    -o-transform: translateY(-40px);
    transform: translateY(-40px); } }
@keyframes passing-through {
  0% {
    opacity: 0;
    -webkit-transform: translateY(40px);
    -moz-transform: translateY(40px);
    -ms-transform: translateY(40px);
    -o-transform: translateY(40px);
    transform: translateY(40px); }
  30%, 70% {
    opacity: 1;
    -webkit-transform: translateY(0px);
    -moz-transform: translateY(0px);
    -ms-transform: translateY(0px);
    -o-transform: translateY(0px);
    transform: translateY(0px); }
  100% {
    opacity: 0;
    -webkit-transform: translateY(-40px);
    -moz-transform: translateY(-40px);
    -ms-transform: translateY(-40px);
    -o-transform: translateY(-40px);
    transform: translateY(-40px); } }
@-webkit-keyframes slide-in {
  0% {
    opacity: 0;
    -webkit-transform: translateY(40px);
    -moz-transform: translateY(40px);
    -ms-transform: translateY(40px);
    -o-transform: translateY(40px);
    transform: translateY(40px); }
  30% {
    opacity: 1;
    -webkit-transform: translateY(0px);
    -moz-transform: translateY(0px);
    -ms-transform: translateY(0px);
    -o-transform: translateY(0px);
    transform: translateY(0px); } }
@-moz-keyframes slide-in {
  0% {
    opacity: 0;
    -webkit-transform: translateY(40px);
    -moz-transform: translateY(40px);
    -ms-transform: translateY(40px);
    -o-transform: translateY(40px);
    transform: translateY(40px); }
  30% {
    opacity: 1;
    -webkit-transform: translateY(0px);
    -moz-transform: translateY(0px);
    -ms-transform: translateY(0px);
    -o-transform: translateY(0px);
    transform: translateY(0px); } }
@keyframes slide-in {
  0% {
    opacity: 0;
    -webkit-transform: translateY(40px);
    -moz-transform: translateY(40px);
    -ms-transform: translateY(40px);
    -o-transform: translateY(40px);
    transform: translateY(40px); }
  30% {
    opacity: 1;
    -webkit-transform: translateY(0px);
    -moz-transform: translateY(0px);
    -ms-transform: translateY(0px);
    -o-transform: translateY(0px);
    transform: translateY(0px); } }
@-webkit-keyframes pulse {
  0% {
    -webkit-transform: scale(1);
    -moz-transform: scale(1);
    -ms-transform: scale(1);
    -o-transform: scale(1);
    transform: scale(1); }
  10% {
    -webkit-transform: scale(1.1);
    -moz-transform: scale(1.1);
    -ms-transform: scale(1.1);
    -o-transform: scale(1.1);
    transform: scale(1.1); }
  20% {
    -webkit-transform: scale(1);
    -moz-transform: scale(1);
    -ms-transform: scale(1);
    -o-transform: scale(1);
    transform: scale(1); } }
@-moz-keyframes pulse {
  0% {
    -webkit-transform: scale(1);
    -moz-transform: scale(1);
    -ms-transform: scale(1);
    -o-transform: scale(1);
    transform: scale(1); }
  10% {
    -webkit-transform: scale(1.1);
    -moz-transform: scale(1.1);
    -ms-transform: scale(1.1);
    -o-transform: scale(1.1);
    transform: scale(1.1); }
  20% {
    -webkit-transform: scale(1);
    -moz-transform: scale(1);
    -ms-transform: scale(1);
    -o-transform: scale(1);
    transform: scale(1); } }
@keyframes pulse {
  0% {
    -webkit-transform: scale(1);
    -moz-transform: scale(1);
    -ms-transform: scale(1);
    -o-transform: scale(1);
    transform: scale(1); }
  10% {
    -webkit-transform: scale(1.1);
    -moz-transform: scale(1.1);
    -ms-transform: scale(1.1);
    -o-transform: scale(1.1);
    transform: scale(1.1); }
  20% {
    -webkit-transform: scale(1);
    -moz-transform: scale(1);
    -ms-transform: scale(1);
    -o-transform: scale(1);
    transform: scale(1); } }
.dropzone, .dropzone * {
  box-sizing: border-box; }

.dropzone {
    width:110px;
  min-height: 90px;
  border: 2px solid rgba(0, 0, 0, 0.3);
  background: white;
  padding: 0px 0px; }
  .dropzone.dz-clickable {
    cursor: pointer; }
    .dropzone.dz-clickable * {
      cursor: default; }
    .dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * {
      cursor: pointer; }
  .dropzone.dz-started .dz-message {
    display: none; }
  .dropzone.dz-drag-hover {
    border-style: solid; }
    .dropzone.dz-drag-hover .dz-message {
      opacity: 0.5; }
  .dropzone .dz-message {
    text-align: center;
   }
  .dropzone .dz-preview {
    position: relative;
    display: inline-block;
    vertical-align: top;
    margin: 2px;
    min-height: 100px; }
    .dropzone .dz-preview:hover {
      z-index: 1000; }
      .dropzone .dz-preview:hover .dz-details {
        opacity: 1; }
    .dropzone .dz-preview.dz-file-preview .dz-image {
      border-radius: 20px;
      background: #999;
      background: linear-gradient(to bottom, #eee, #ddd); }
    .dropzone .dz-preview.dz-file-preview .dz-details {
      opacity: 1; }
    .dropzone .dz-preview.dz-image-preview {
      background: white; }
      .dropzone .dz-preview.dz-image-preview .dz-details {
        -webkit-transition: opacity 0.2s linear;
        -moz-transition: opacity 0.2s linear;
        -ms-transition: opacity 0.2s linear;
        -o-transition: opacity 0.2s linear;
        transition: opacity 0.2s linear; }
    .dropzone .dz-preview .dz-remove {
      font-size: 14px;
      text-align: center;
      display: block;
      cursor: pointer;
      border: none; }
      .dropzone .dz-preview .dz-remove:hover {
        text-decoration: underline; }
    .dropzone .dz-preview:hover .dz-details {
      opacity: 1; }
    .dropzone .dz-preview .dz-details {
      z-index: 20;
      position: absolute;
      top: 0;
      left: 0;
      opacity: 0;
      font-size: 13px;
      min-width: 100%;
      max-width: 100%;
      padding: 2em 1em;
      text-align: center;
      color: rgba(0, 0, 0, 0.9);
      line-height: 150%; }
      .dropzone .dz-preview .dz-details .dz-size {
        margin-bottom: 1em;
        font-size: 16px; }
      .dropzone .dz-preview .dz-details .dz-filename {
        white-space: nowrap; }
        .dropzone .dz-preview .dz-details .dz-filename:hover span {
          border: 1px solid rgba(200, 200, 200, 0.8);
          background-color: rgba(255, 255, 255, 0.8); }
        .dropzone .dz-preview .dz-details .dz-filename:not(:hover) {
          overflow: hidden;
          text-overflow: ellipsis; }
          .dropzone .dz-preview .dz-details .dz-filename:not(:hover) span {
            border: 1px solid transparent; }
      .dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span {
        background-color: rgba(255, 255, 255, 0.4);
        padding: 0 0.4em;
        border-radius: 3px; }
    .dropzone .dz-preview:hover .dz-image img {
      -webkit-transform: scale(1.05, 1.05);
      -moz-transform: scale(1.05, 1.05);
      -ms-transform: scale(1.05, 1.05);
      -o-transform: scale(1.05, 1.05);
      transform: scale(1.05, 1.05);
      -webkit-filter: blur(8px);
      filter: blur(8px); }
    .dropzone .dz-preview .dz-image {
      border-radius: 20px;
      overflow: hidden;
      width: 100px;
      height: 100px;
      position: relative;
      display: block;
      z-index: 10; }
      .dropzone .dz-preview .dz-image img {
        display: block; }
    .dropzone .dz-preview.dz-success .dz-success-mark {
      -webkit-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
      -moz-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
      -ms-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
      -o-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
      animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); }
    .dropzone .dz-preview.dz-error .dz-error-mark {
      opacity: 1;
      -webkit-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
      -moz-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
      -ms-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
      -o-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
      animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); }
    .dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark {
      pointer-events: none;
      opacity: 0;
      z-index: 500;
      position: absolute;
      display: block;
      top: 50%;
      left: 50%;
      margin-left: -27px;
      margin-top: -27px; }
      .dropzone .dz-preview .dz-success-mark svg, .dropzone .dz-preview .dz-error-mark svg {
        display: block;
        width: 54px;
        height: 54px; }
    .dropzone .dz-preview.dz-processing .dz-progress {
      opacity: 1;
      -webkit-transition: all 0.2s linear;
      -moz-transition: all 0.2s linear;
      -ms-transition: all 0.2s linear;
      -o-transition: all 0.2s linear;
      transition: all 0.2s linear; }
    .dropzone .dz-preview.dz-complete .dz-progress {
      opacity: 0;
      -webkit-transition: opacity 0.4s ease-in;
      -moz-transition: opacity 0.4s ease-in;
      -ms-transition: opacity 0.4s ease-in;
      -o-transition: opacity 0.4s ease-in;
      transition: opacity 0.4s ease-in; }
    .dropzone .dz-preview:not(.dz-processing) .dz-progress {
      -webkit-animation: pulse 6s ease infinite;
      -moz-animation: pulse 6s ease infinite;
      -ms-animation: pulse 6s ease infinite;
      -o-animation: pulse 6s ease infinite;
      animation: pulse 6s ease infinite; }
    .dropzone .dz-preview .dz-progress {
      opacity: 1;
      z-index: 1000;
      pointer-events: none;
      position: absolute;
      height: 16px;
      left: 50%;
      top: 50%;
      margin-top: -8px;
      width: 80px;
      margin-left: -40px;
      background: rgba(255, 255, 255, 0.9);
      -webkit-transform: scale(1);
      border-radius: 8px;
      overflow: hidden; }
      .dropzone .dz-preview .dz-progress .dz-upload {
        background: #333;
        background: linear-gradient(to bottom, #666, #444);
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        width: 0;
        -webkit-transition: width 300ms ease-in-out;
        -moz-transition: width 300ms ease-in-out;
        -ms-transition: width 300ms ease-in-out;
        -o-transition: width 300ms ease-in-out;
        transition: width 300ms ease-in-out; }
    .dropzone .dz-preview.dz-error .dz-error-message {
      display: block; }
    .dropzone .dz-preview.dz-error:hover .dz-error-message {
      opacity: 1;
      pointer-events: auto; }
    .dropzone .dz-preview .dz-error-message {
      pointer-events: none;
      z-index: 1000;
      position: absolute;
      display: block;
      display: none;
      opacity: 0;
      -webkit-transition: opacity 0.3s ease;
      -moz-transition: opacity 0.3s ease;
      -ms-transition: opacity 0.3s ease;
      -o-transition: opacity 0.3s ease;
      transition: opacity 0.3s ease;
      border-radius: 8px;
      font-size: 13px;
      top: 130px;
      left: -10px;
      width: 110px;
      background: #be2626;
      background: linear-gradient(to bottom, #be2626, #a92222);
      padding: 0.5em 1.2em;
      color: white; }
      .dropzone .dz-preview .dz-error-message:after {
        content: '';
        position: absolute;
        top: -6px;
        left: 64px;
        width: 0;
        height: 0;
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-bottom: 6px solid #be2626; }
View Code

》需要引用的文件

<link rel="stylesheet" href="~/assets/dropzone/dist/dropzone.css" />
<script type="text/javascript" src="~/assets/dropzone/dist/dropzone.js"></script>

html中定义class为dropzone的dom,作为上传控件

 <div class="dropzone" id="my-dropzone"></div>

    //Dropzone的初始化
    Dropzone.options.myDropzone = {

        //指定上传图片的路径
        url: '/DC/File/ReportFileUpload',
        method: "post",  //也可用put
        paramName: "file", //默认为file
        maxFiles: 1,//一次性上传的文件数量上限
        maxFilesize: 10, //文件大小,单位:MB
        acceptedFiles: "*", //上传的类型
        addRemoveLinks: true, //添加上传取消和删除预览图片的链接,默认不添加
        autoProcessQueue: true,//关闭自动上传功能,默认会true会自动上传
        uploadMultiple: false,//允许上传多个照片
        parallelUploads: 1,//每次上传的最多文件数,经测试默认为2,坑啊,记得修改web.config 限制上传文件大小的节
        dictDefaultMessage: '拖动文件至此或者点击上传',
        dictMaxFilesExceeded: "您最多只能上传1个文件!",
        dictResponseError: '文件上传失败!',
        dictInvalidFileType: "",
        dictFallbackMessage: "浏览器不受支持",
        dictFileTooBig: "文件过大上传文件最大支持.",
        dictRemoveLinks: "删除",
        dictCancelUpload: "取消",
        init: function () {
            myDropzone = this; // closure
            this.on("addedfile", function () {
                this.options.headers = { "id": $('#ID').val() };
                $('.modal-dialog .btn-primary').attr("disabled", true);
            });
            //当上传完成后的事件,接受的数据为JSON格式
            this.on("complete", function (data) {
                $('.modal-dialog .btn-primary').removeAttr("disabled");
                if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) {
                    // var res = eval('(' + data.xhr.responseText + ')');
                    var res = JSON.parse(data.xhr.responseText)

                    if (res.state) {
                      //do something
                    }
                    else {
                        CM.showMsg('上传文件失败!');
                    }
                }
            });

            //删除图片的事件,当上传的图片为空时,使上传按钮不可用状态
            this.on("removedfile", function () {
                if (this.getAcceptedFiles().length === 0) {
                    $("#filename").val('');
                    $("#filepath").val('');
                }
            });
        }
    };


 function removeDropzoneFile() {
        //去除Dropzone已经存在的图片
        if (!CM.isNull(myDropzone) && myDropzone.files.length != 0) {
            for (var i = 0; i < myDropzone.files.length; i++) {
                myDropzone.removeFile(myDropzone.files[0]);
            }
        }
    }
View Code

 后台的接收方法

public JsonResult ReportFileUpload()
        {
            string physicalFolderPath = string.Empty;//物理文件夹路径
            HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;

            if (string.IsNullOrEmpty(this.reportFolderPath))
            {
                // physicalFolderPath = Server.MapPath(@"FilesReportFiles");
                physicalFolderPath = "/Files/ReportFiles";
            }
            else
            {
                physicalFolderPath = this.reportFolderPath;
            }

            return Upload(hfc, physicalFolderPath,"");
        }


 /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="hfc">文件信息</param>
        /// <param name="physicalFolderPath">物理文件存储文件夹绝对路径</param>
        /// <returns></returns>
        private JsonResult Upload(HttpFileCollection hfc, string physicalFolderPath,string guid)
        {
            try
            {
                string msg = "位置错误!";
                string physicalFullPath = string.Empty;
                string fileName = string.Empty;
                bool isSuccess = false;
                var files = Request.Files;
                if (guid == "") {
                    guid = Guid.NewGuid().ToString();
                }
               
                if (hfc != null && hfc.Count > 0)
                {
                    try
                    {
                        fileName = hfc[0].FileName;
                        if (!string.IsNullOrEmpty(fileName))
                        {
                          
                            string save_dir= Server.MapPath(physicalFolderPath);
                          
                            if (!Directory.Exists(save_dir))
                            {
                                Directory.CreateDirectory(save_dir);
                            }
                            physicalFullPath = physicalFolderPath + "/" + guid + Path.GetExtension(fileName);
                            string savepath = Server.MapPath(physicalFullPath) ;
                            hfc[0].SaveAs(savepath);
                            isSuccess = true;
                            msg = "上传成功!";
                        }
                        else
                        {
                            msg = "未识别任何有效文件!";
                        }

                    }
                    catch (Exception e)
                    {
                        msg = e.Message;
                    }
                }

                return Json(new { state = isSuccess, message = msg,guid= guid, fileName = fileName, filePath = physicalFullPath }, JsonRequestBehavior.AllowGet);
            }
            catch {
                return Json(new { state = false, message = "上传文件失败!" }, JsonRequestBehavior.AllowGet);
            }
        }
View Code

附:dropzone常用配置项

url : 必要参数,文件的上传地址;
maxFiles : 默认为null,可以指定为一个数值,限制最多文件数量。
maxFilesize : 限制文件的大小,单位是MB;
acceptedFiles : 允许上传的文件类型,文件扩展名以逗号隔开,格式见实例;
autoProcessQueue : 默认为true,即拖入文件立即自动上传;如果需要在上传之前有一些选择的操作,然后手动上传,可以把该属性设置为false,然后手动点击按钮上传;
paramName : 相当于<input>元素的name属性,默认为file。
提示文本:
dictDefaultMessage : 没有任何文件被添加时的提示文本;
dictFallbackMessage:Fallback 情况下的提示文本。
dictInvalidInputType:文件类型被拒绝时的提示文本。
dictFileTooBig:文件大小过大时的提示文本。
dictCancelUpload:取消上传链接的文本。
dictCancelUploadConfirmation:取消上传确认信息的文本。
dictRemoveFile:移除文件链接的文本。
dictMaxFilesExceeded:超过最大文件数量的提示文本。
View Code

附:dropzone常用事件

addedfile : 添加文件是发生
removefile : 手动从服务器删除文件时发生
success : 上传成功后发生
complete:当文件上传成功或失败之后发生。
canceled:当文件在上传时被取消的时候发生。
maxfilesreached:当文件数量达到最大时发生。
maxfilesexceeded:当文件数量超过限制时发生。
totaluploadprogress : 文件上传中的返回值,第一个参数为总上传进度(0到100),第二个为总字节数,第三个为总上传字节数,利用这几个参数,可计算出上传速度,和剩余上传时间;
View Code
原文地址:https://www.cnblogs.com/eye-like/p/10266618.html