文件上传到应用服务器

该文详细介绍了如何使用HTML和JavaScript实现Base64编码和file对象两种方式上传图片,并对比了它们的上传速度和限制。在不设置上传大小限制时,Base64上传适合小文件,而file对象上传能处理更大文件且速度更快。在处理图片预览和特殊字符文件名时,两者各有优缺点。文章提供了具体的HTML结构、CSS样式和JS代码示例,以及后台处理程序的C#代码片段。
摘要由CSDN通过智能技术生成

将文件转换成Base64编码和file对象上传文件

下文中,将文件转换成Base64编码上传文件,简称为:Base64。file对象上传文件,简称为:file。
本文主要以上传图片为例,如果上传其他类型的文件,可能会有一些差异。
HTML

<div class="layui-fluid">
        <div class="layui-col-lg6 col_left">
            <div class="col_title">Base64上传文件</div>
            <div class="btn_file">
                <button type="button" class="layui-btn" id="btn_base64" onclick="f_base64.click();"><i class="layui-icon"></i>上传图片<sapn class="time_base64"></sapn></button>
                <input type="file" id="f_base64" multiple="multiple" accept="image/jpg,image/jpeg,image/png" style="display:none;" onchange="UpfileCheck(this,'base64')" />
            </div>
            <div class="preview_img_base64">
                <div class="col_title">Img</div>

            </div>
            <div class="preview_bimg_base64">
                <div class="col_title">Background-image</div>

            </div>
        </div>
        <div class="layui-col-lg6 col_right">
            <div class="col_title">file对象上传文件</div>
            <div class="btn_file">
                <button type="button" class="layui-btn" id="btn_file" onclick="f_flie.click();"><i class="layui-icon"></i>上传图片<sapn class="time_files"></sapn></button>
                <input type="file" id="f_flie" multiple="multiple" accept="image/jpg,image/jpeg,image/png" style="display:none;" onchange="UpfileCheck(this,'files')" />
            </div>
            <div class="preview_img_files">
                <div class="col_title">Img</div>

            </div>
            <div class="preview_bimg_files">
                <div class="col_title">Background-image</div>

            </div>
        </div>
    </div>

CSS

 <link rel="stylesheet" href="/css/style.css" />
    <link rel="stylesheet" href="/js/layui/css/layui.css">
    <style type="text/css">
        .layui-fluid {
            padding: 10px;
        }

        .col_left {
            border-right: 1px solid rgb(203, 200, 200);
        }

        .col_right {
            padding-left: 10px;
        }

        .col_title {
            font-size: 16px;
            font-weight: bold;
            text-align: center;
        }

        .preview_img_base64, .preview_bimg_base64 {
            margin-top: 10px;
        }

            .preview_img_base64 img {
                width: 150px;
                height: 150px;
                object-fit: cover;
                box-shadow: 0 1px 5px rgba(0,0,0,.2);
            }

        .preview_bimg_photo {
            height: 150px;
            width: 150px;
            background: no-repeat 50%;
            background-size: cover;
            box-shadow: 0 1px 5px rgba(0,0,0,.2);
            float: left;
        }

        .preview_img_files, .preview_bimg_files {
            margin-top: 10px;
        }

            .preview_img_files img {
                width: 150px;
                height: 150px;
                object-fit: cover;
                box-shadow: 0 1px 5px rgba(0,0,0,.2);
            }
    </style>

JS

<script src="/js/layui/layui.js"></script>
    <script src="/js/jquery/jquery-3.2.1.min.js"></script>
    <script type="text/javascript">
        var fl = 0;//文件数量
        var upload_num = 0;//文件上传索引
        var file_array = [];//文件数组
        var upload_mask;//文件上传遮罩
        var st_base64;//base64上传文件开始时间
        var st_files;//file对象上传文件开始
        var et_base64;//base64上传文件结束时间
        var et_files;//file对象上传文件结束时间
        //文件上传初始化
        function UpfileCheck(t, upload_flag) {
            fl = t.files.length;//获取文件数量
            upload_num = 0;//初始化文件上传索引
            file_array = [];//文件数组
            //需要判断是否选择图片,否则第一次选择图片后,第二次选择图片取消也会触发上传
            if (fl > 0) {
                upload_mask = layer.load(1, {
                    content: '上传中...',
                    shade: [0.4, '#393D49'],
                    success: function (layero) {
                        layero.find('.layui-layer-content').css({
                            'padding-top': '39px',
                            'width': '200px',
                            'color': '#fff',
                            'text-align': 'left'
                        });
                    }
                });
                if (upload_flag == 'base64') {
                    st_base64 = new Date();
                    console.log(st_base64);
                    setTimeout(function () { UpfileBase64(t, upload_num); }, 500);
                }
                else {
                    st_files = new Date();
                    console.log(st_files);
                    setTimeout(function () { UpfileFiles(t, upload_num);}, 500);
                    
                }
            }
            else {
                layer.msg('请选择需要上传的文件!');
            }
        }
        //将文件转换为base64编码
        function UpfileBase64(t, f_num) {
            var filename = t.files[f_num].name;//文件名
            var houzui = filename.lastIndexOf('.'); //获取 . 出现的位置
            var ext = filename.substring(houzui, filename.length).toUpperCase();  //切割 . 获取文件后缀

            var reader = new FileReader();
            reader.readAsDataURL(t.files[f_num]); //将读取到的文件编码成Data URL
            reader.onload = function () { //读取完成时
                var replaceSrc = reader.result; //文件输出的内容
                //将文件放入文件数组中
                file_array.push({ base64_code: replaceSrc, filename: filename, ext: ext, src: '/upload/img/' });

                upload_num++;
                if (upload_num >= fl) {
                    AjaxUploadBase64(); //ajax上传base64编码的文件
                    $("#f_base64").val("");//清空文件控件
                }
                else {
                    UpfileBase64(t, upload_num);//继续读取文件
                }
            }
        }

        //ajax上传base64编码的文件
        function AjaxUploadBase64() {
            //判断文件数组中是否存在文件
            if (file_array.length > 0) {
                //遍历数组中的文件上传到应用服务器
                for (var i = 0; i < file_array.length; i++) {
                    $.ajax({
                        type: "post",
                        url: "/UploadFile/ashx/UploadImg.ashx",
                        data: { fun: "UploadImgBase64", strbase64: file_array[i]["base64_code"], src: file_array[i]["src"], filename: file_array[i]["filename"] },
                        dataType: "json",
                        async: false,
                        success: function (data) {
                            if (data.ajaxDataFlag) {
                                PreviewBImg(data.ajaxresult, 'Base64');//预览图片
                            }
                            else {
                                layer.msg("上传失败:" + data.ajaxresult);
                            }
                        },
                        error: function (event, XMLHttpRequest, ajaxOptions, thrownError) {
                            // thrownError 只有当异常发生时才会被传递 this;
                            var resStr = event.statusText
                            layer.msg("上传失败:" + resStr);
                        }

                    });
                }
            }
            layer.close(upload_mask);
            et_base64 = new Date();
            console.log(et_base64);
        }

        //使用file对象上传文件
        function UpfileFiles(t, f_num) {
            var imgData = new FormData();
            imgData.append('fun', 'UploadImgFiles');//文件上传方法名
            imgData.append('file', t.files[f_num]);//file对象
            imgData.append('src', "/upload/img/");//上传文件存放地址
            
            $.ajax({
                type: "POST",
                url: "/UploadFile/ashx/UploadImg.ashx",
                data: imgData,
                processData: false,//防止将发送的数据序列
                contentType: false,//默认值: true。默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 “application/x-www-form-urlencoded”。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。
                dataType: "json",
                async: false,
                success: function (data) {
                    PreviewBImg(data.ajaxresult, 'Files');//预览图片
                    upload_num++;//更新文件索引
                    //文件未上传完成继续上传
                    if (upload_num < fl) {
                        UpfileFiles(t, upload_num);//继续上传
                    }
                    else {
                        et_files = new Date();
                        console.log(et_files);
                        layer.close(upload_mask);
                    }
                        
                },
                error: function (event, XMLHttpRequest, ajaxOptions, thrownError) {
                    // thrownError 只有当异常发生时才会被传递 this;
                    var resStr = event.statusText
                    layer.msg("上传失败:" + resStr);
                }
            })
        }

        //预览图片
        function PreviewBImg(src, up_flag) {
            var htmlimg = "<img src='" + src + "' />";
            var htmlbimg = "<div style='background-image:url(" + src + ")' class='preview_bimg_photo'> </div>";
            if (up_flag == 'Base64') {
                $(".preview_img_base64").append(htmlimg);
                $(".preview_bimg_base64").append(htmlbimg);
            }
            else if (up_flag == 'Files') {
                $(".preview_img_files").append(htmlimg);
                $(".preview_bimg_files").append(htmlbimg);
            }

        }

    </script>

一般处理程序

 #region ajax上传base64编码的文件
        public string UploadImgBase64(HttpContext context)
        {
            string strbase64 = context.Request.QueryString["strbase64"] ?? context.Request.Form["strbase64"];
            string src = context.Request.QueryString["src"] ?? context.Request.Form["src"];
            string filename = context.Request.QueryString["filename"] ?? context.Request.Form["filename"];
            try
            {
                //获取base64编码
                string dummyData = strbase64.Replace("data:audio/mp3;base64,", "").Replace("data:application/pdf;base64,", "").Replace("data:image/gif;base64,", "").Replace("data:image/jpeg;base64,", "").Replace("data:image/png;base64,", "").Replace("%", "").Replace(",", "").Replace(" ", "+");
                if (dummyData.Length % 4 > 0)
                {
                    dummyData = dummyData.PadRight(dummyData.Length + 4 - dummyData.Length % 4, '=');
                }

                //文件上传路径+年月日
                src = src + DateTime.Now.ToString("yyMMdd") + "/";
                string uploadPath = context.Request.PhysicalApplicationPath + src;//获取文件在应用服务器存放的绝对路径
                //判断文件上传路径文件夹是否存在
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);//创建文件夹
                }
                //上传文件
                FileStream fs = null;
                Random rd = new Random();
                fs = File.Create(uploadPath + filename);
                byte[] bytes = Convert.FromBase64String(dummyData);
                fs.Write(bytes, 0, bytes.Length);
                fs.Close();//释放资源,否则图片一直被占用

                //文件HTTP路径,域名+端口+文件上传路径+文件名
                string httpPath = "http://" + context.Request.Url.Host + ":" + context.Request.Url.Port + src + filename;

                at.ajaxDataFlag = true;
                at.ajaxresult = httpPath;
            }
            catch (Exception ex)
            {
                at.ajaxDataFlag = false;
                at.ajaxresult = "服务器内部错误,请联系开发人员!";
                ALogOut.debug(ex.ToString());//记录错误日志
            }
            return JsonConvert.SerializeObject(at);//返回结果
        }
        #endregion

        #region 使用file对象上传文件
        public string UploadImgFiles(HttpContext context)
        {
            HttpPostedFile files = context.Request.Files["file"];
            string src = context.Request.QueryString["src"] ?? context.Request.Form["src"];
            try
            {
                //文件上传路径+年月日
                src = src + DateTime.Now.ToString("yyMMdd") + "/";
                string uploadPath = context.Request.PhysicalApplicationPath + src;//获取文件在应用服务器存放的绝对路径
                //判断文件上传路径文件夹是否存在
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);//创建文件夹
                }
                //上传文件至应用服务器
                files.SaveAs(uploadPath + files.FileName);

                Image pic = Image.FromFile(uploadPath + files.FileName);//图片的绝对路径 
                int intWidth = pic.Width;//长度像素值 
                int intHeight = pic.Height;//高度像素值 
                pic.Dispose();//释放资源

                //文件HTTP路径,域名+端口+文件上传路径+文件名
                string httpPath = "http://" + context.Request.Url.Host + ":" + context.Request.Url.Port + src + files.FileName;

                at.ajaxDataFlag = true;
                at.ajaxresult = httpPath;
                at.ajaxString = uploadPath + files.FileName;//文件在应用服务器的绝对路径
            }
            catch (Exception ex)
            {
                at.ajaxDataFlag = false;
                at.ajaxresult = "服务器内部错误,请联系开发人员!";
                ALogOut.debug(ex.ToString());
            }
            return JsonConvert.SerializeObject(at);
        }
        #endregion

页面效果
在这里插入图片描述
页面分为了“Base64上传文件”和“file对象上传文件”左右两部分,用于对两种上传方式进行测试,同时针对图片展示分为了“img”和“Background-image”两种方式呈现。
测试结果:
1.在不设置上传文件上传大小的情况下,Base64上传的图片大小为2~3M,file上传的文件大小不能大于等于4M。
2.设置文件上传大小为500M后,Base64无法上传超过20M的图片,file可以上传20M以上的图片(上限未测试)。(web.config配置)
3.file上传文件比Base64更快。
4.img和Background-image图片显示速度相同。
5.Background-image无法显示文件名带有特殊字符的图片,如:空格、()等。(解决方案:一是上传时不允许上传文件名带有特殊字符或者重命名取消特殊字符。二是将文件名中的特殊字符进行转义。)
6.file上传图片时,可以在一般处理程序中获取图片的尺寸,详情见代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值