精选文章 前端大文件上传解决方案

前端大文件上传解决方案

作者:M_Snow 时间: 2019-11-07 12:03:56
M_Snow 2019-11-07 12:03:56

本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案。见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案。

本人在2013年时使用plupload为核心进行文件的批量上传的解决方案。见文章:WEB版一次选择多个文件进行批量上传(Plupload)的解决方案

最近在学习百度的开源上传组件WebUploader,写了一些示例以记录。WebUploader的缺点是没有一个比较好的现成的界面,这个界面需要自己去实现。自由度高了一些。

WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。浏览器支持ie6,ie7,ie8,ie9,ie10,ie11,firefox,chrome,edge。支持全平台操作系统:Windows,Mac,Linux支持文件夹上传下载,文件批量上传下载,层级目录保存。

 

关于WebUploader的功能说明:

 

大文件上传续传

支持超大文件上传(100G+)和续传,可以关闭浏览器,重启系统后仍然继续上传。
开源
提供ASP.NET,JSP,PHP示例和源代码,其中JSP提供MySQL,Oracle,SQL Server数据库的配置和示例代码。

分片、并发

分片与并发结合,将一个大文件分割成多块,并发上传,极大地提高大文件的上传速度。

当网络问题导致传输错误时,只需要重传出错分片,而不是整个文件。另外分片传输能够更加实时的跟踪上传进度。

预览、压缩

支持常用图片格式jpg,jpeg,gif,bmp,png预览与压缩,节省网络数据传输。

解析jpeg中的meta信息,对于各种orientation做了正确的处理,同时压缩后上传保留图片的所有原始meta数据。

多途径添加文件

支持文件多选,类型过滤,拖拽(文件&文件夹),图片粘贴功能。上传本地指定路径的文件,不需要通过点击按钮选择文件。

粘贴功能主要体现在当有图片数据在剪切板中时(截屏工具如QQ(Ctrl + ALT + A), 网页中右击图片点击复制),Ctrl + V便可添加此图片文件。

HTML5 & FLASH

兼容主流浏览器和低版本浏览器,接口一致,实现了两套运行时支持,用户无需关心内部用了什么内核。而且支持IE6,IE8浏览器。

同时Flash部分没有做任何UI相关的工作,方便不关心flash的用户扩展和自定义业务需求。

基于内存映射模式进行IO操作,充分发挥操作系统性能。
MD5秒传

 

当文件体积大、量比较多时,支持上传前做文件md5值验证,一致则可直接跳过。

如果服务端与前端统一修改算法,取段md5,可大大提升验证性能,耗时在20ms左右。

易扩展、可拆分

采用可拆分机制, 将各个功能独立成了小组件,可自由搭配。

采用AMD规范组织代码,清晰明了,方便高级玩家扩展。

文件夹上传

支持10万+级别的文件夹上传,续传。

支持层级目录结构保存,上传后能够将数据库层级信息保存在数据库中。
提供MySQL,Oracle,SQL Server数据库支持。

支持文件夹续传,在浏览器刷新,重启后仍然能够继续上传。

支持跨域上传。

PC端全平台支持
支持Windows,macOS,Linux。支持国产化操作系统,支持政务信息安全项目。
其中Windows支持低版本系统:Windows XP。
其中浏览器包括:IE6,IE7,IE8(x86,x64),IE9(x86,x64),IE10(x86,x64),IE11(x86,x64),360安全浏览器,360极速浏览器,QQ浏览器,搜狗浏览器,Maxthon(遨游)浏览器1.X,Maxthon(傲游)浏览器2.x,Firefox,Chrome,Opera 23+

 

一: 下面就是利用WebUploader组件,让客户一次选择多个文件,然后将选择的文件上传到服务器的批量文件解决方案。

让我们先来看看客户端的界面效果图。(多选文件,批量上传,上传进度显示)

1) 显示界面:

前端大文件上传解决方案1

图1

2) 进行多文件选择:

 前端大文件上传解决方案2

                                           图2

 

3) 上传进度显示

 前端大文件上传解决方案3 前端大文件上传解决方案4

                                       图3

 前端大文件上传解决方案5

                       图4

说明:见上图WebUploader默认是3个线程一起并发上传文件。如果需要增加并发数,或是减少并发数。可以修改threads属性,这个属性就是允许的最大上传并发数。

 

3) 上传成功显示

前端大文件上传解决方案6

                       图5

 

二:具体的代码与操作步骤:

 

第一步,要完成下面的示例,必须先准备好WebUploader组件。

1) WebUploader:大家可以访问WebUploader官方网站:http://www.webuploader.net,在这个网站上可以下载到组件与demo。

 

第二步,这个示例的目录结构如图:

1.主要目录结构

 前端大文件上传解决方案7

2. 此示例中用到的js脚本文件与css文件。

  前端大文件上传解决方案8

第三步,前台部分准备客户操作的WEB界面,如下[WebUploaderFileByBaidu2.aspx、UploaderFileByBaidu.ashx]

 

1)  前台客户端代码,其中WebUploaderFileByBaidu2.aspx的代码如下,WebUploaderFileByBaidu2.aspx.cs文件中只使用默认的代码,不用添加任何代码。

 

Html代码

前端大文件上传解决方案9

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebUploaderFileByBaidu2.aspx.cs" Inherits="WebApplication1.WebUploaderFileByBaidu2" %>

    WebUploader文件上传示例

 

      

      

    

 

      

    

    

    

 

     

         var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "../../";

         // 文件上传         jQuery(function () {

             var $ = jQuery,

                 $list = $('#fileList'),

                 $btn = $('#ctlBtn'),

                 state = 'pending',

                 uploader;

             uploader = WebUploader.create({

                 // 不压缩image

                 resize: false,

 

                 // swf文件路径

                 swf: applicationPath + 'Script/webuploader/Uploader.swf',

 

                 // 文件接收服务端。

                 server: 'UploaderFileByBaidu.ashx',

 

                 // 选择文件的按钮。可选。

                 // 内部根据当前运行是创建,可能是input元素,也可能是flash.

                 pick: '#picker'

 

             });

 

             // 当有文件添加进来的时候

             uploader.on('fileQueued', function (file) {

 

                 $list.append('

' +

                     '

' + file.name + '

' +

                     '

等待上传...

' +

                 '

');

 

             });

 

             // 文件上传过程中创建进度条实时显示。

             uploader.on('uploadProgress', function (file, percentage) {

 

                 var $li = $('#' + file.id),

                     $percent = $li.find('.progress .progress-bar');

                 // 避免重复创建

                 if (!$percent.length) {

                     $percent = $('

' +

                       '

' +

                       '

' +

                     '

').appendTo($li).find('.progress-bar');

                 }

                 $li.find('p.state').text('上传中');

                 $percent.css('width', percentage * 100 + '%');

 

             });

 

             uploader.on('uploadSuccess', function (file) {

                 $('#' + file.id).find('p.state').text('已上传');

             });

 

             uploader.on('uploadError', function (file) {

                 $('#' + file.id).find('p.state').text('上传出错');

             });

 

             uploader.on('uploadComplete', function (file) {

                 $('#' + file.id).find('.progress').fadeOut();

             });

             uploader.on('all', function (type) {

                 if (type === 'startUpload') {

                     state = 'uploading';

                 } else if (type === 'stopUpload') {

                     state = 'paused';

                 } else if (type === 'uploadFinished') {

                     state = 'done';

                 }

                 if (state === 'uploading') {

                     $btn.text('暂停上传');

                 } else {

                     $btn.text('开始上传');

                 }

 

             });

 

             $btn.on('click', function () {

                 if (state === 'uploading') {

                     uploader.stop();

                 } else {

                     uploader.upload();

                 }

             });

         });

    

 

    

        

        文件上传示例:

         

  

    

    

    

        选择文件   

 

    

             

 

          

 

    

          开始上传

    

    

    

    

前端大文件上传解决方案10

 

以上代码最后的显示结果如下图:

 前端大文件上传解决方案11

                                      图8.

 

2) 接收前端用户上传的文件,并把文件保存到指定目录中。UploaderFileByBaidu.ashx文件中使用默认的代码,不需要添加任何代码。UploaderFileByBaidu.ashx.cs文件的代码如下: 

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Web;namespace WebApplication1

{

    /// 

    /// UploaderFileByBaidu 的摘要说明

    ///

    public class UploaderFileByBaidu : IHttpHandler

 

    {

        public void ProcessRequest(HttpContext context)

        {

            context.Response.ContentEncoding = Encoding.UTF8;

            if (context.Request["REQUEST_METHOD"] == "OPTIONS") 

          {

                context.Response.End();

            }

 

            SaveFile();

        }

 

        /// 

        ///文件保存操作

        ///

        /// 

        private void SaveFile(string basePath = "~/Upload/Images/")

        {

    

             basePath = FileHelper.GetUploadPath();

            string Datedir = DateTime.Now.ToString("yy-MM-dd");

            string updir = basePath + "\\" + Datedir;

            string extname = string.Empty;

            string fullname = string.Empty;

            string filename = string.Empty;    

 

            HttpFileCollection files = System.Web.HttpContext.Current.Request.Files;

 

            if (files.Count == 0)

            {

                var result = "{\"jsonrpc\" : \"2.0\", \"error\" :  \"保存失败\",\"id\" :  \"id\"}";

                System.Web.HttpContext.Current.Response.Write(result);

            }

            if (!Directory.Exists(updir))

                Directory.CreateDirectory(updir);

 

            var suffix = files[0].ContentType.Split('/');

            var _suffix = suffix[1].Equals("jpeg", StringComparison.CurrentCultureIgnoreCase) ? "" : suffix[1];

            var _temp = System.Web.HttpContext.Current.Request["name"];

 

            if (!string.IsNullOrEmpty(_temp))

            {

                filename = _temp;

            }

            else

            {

                Random rand = new Random(24 * (int)DateTime.Now.Ticks);

                filename = rand.Next() + "." + _suffix;

            }

 

             fullname = string.Format("{0}\\{1}",updir , filename);

            files[0].SaveAs(fullname);

            var _result = "{\"jsonrpc\" : \"2.0\", \"result\" : null, \"id\" : \"" + filename + "\"}";

            System.Web.HttpContext.Current.Response.Write(_result);

 

        }

 

        public bool IsReusable

        {

 

            get

            {

                return false;

            }

        }

    }

}

 

 第四步:文件辅助类

///

///FileHelper 的摘要说明/// public class FileHelper

{

 

    public FileHelper()

    {

 

        //

        //TODO: 在此处添加构造函数逻辑

        //    }

 

    ///

    ///获取上传目录

    ///

    ///

     public static string GetUploadPath()

        {

 

          string path = HttpContext.Current.Server.MapPath("~/");

          string dirname = GetDirName();

          string uploadDir = path + "\\" + dirname;

          CreateDir(uploadDir);

          return uploadDir;

        }

 

    ///

    ///获取临时目录

    ///

    ///

     public static string GetTempPath()

     {

 

         string path = HttpContext.Current.Server.MapPath("~/");

         string dirname = GetTempDirName();

         string uploadDir = path + "\\" + dirname;

         CreateDir(uploadDir);

         return uploadDir;

     }

 

        private static string GetDirName()

        {

            return System.Configuration.ConfigurationManager.AppSettings["uploaddir"];

 

        }

 

        private static string GetTempDirName()

        {

            return System.Configuration.ConfigurationManager.AppSettings["tempdir"];

        }

 

    public static void CreateDir(string path)

        {

                if (!System.IO.Directory.Exists(path))

                {                 

 

                    System.IO.Directory.CreateDirectory(path);

                }

        }

}

 

第五步,Web.config文件配置信息。

  

      

  

 

  

    

    

  

 

  

    

 

    

     

    

  

    

    

      

        

      

    

  

 

第六步,在进行上传之后,文件保存在对应的日期目录下。如下图。

前端大文件上传解决方案12

 

 

后端代码逻辑大部分是相同的,目前能够支持MySQL,Oracle,SQL。在使用前需要配置一下数据库,可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/09/web%E5%A4%A7%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:python解决微信登录昵称中带有表情emoji报错,亲测有效。

下一篇:Zookeeper之Leader选举源码分析

您可能感兴趣

  • .NET Core:通过Web API进行微服务交互

    目录 介绍 命名协议 MicroCommerce应用程序结构 MicroCommerce应用开发 1.接口项目,微服务接口和模型类 2. ProductCatalog项目 3. ShoppingCart项目 4. ActivityLogger项目 5. WebUI项目,用户界面 6.关于通用功能的几句话 应用测试 结论 缺点 下载源代码26.3 KB 介绍 几乎所有在.NET Core中使用...

  • MemCache详细解读

    本节内容主要关于mencache的工作原理,memcache的应用场景及其应用实例配置,memcache安装部署。 一、Memcached工作原理 1.服务端缓存实现 (1)memcached特性 分布式: 实例和缓存在逻辑上是分离的 普通缓存 Memcached缓存 特 性 缓存与特定的应用实例绑定,每个应用实例只能访问特定的缓存 实例独立于各个应用服务器实例运行,每应用实例可以访问任意缓...

  • 2020B证(安全员)考试及B证(安全员)模拟考试题库

    题库来源:安全生产模拟考试一点通公众号小程序 2020B证(安全员)考试及B证(安全员)模拟考试题库,包含B证(安全员)考试答案解析及B证(安全员)模拟考试题库练习。由安全生产模拟考试一点通公众号结合国家B证(安全员)考试最新大纲及B证(安全员)考试真题出具,有助于B证(安全员)考试软件考前练习。 1、【单选题】多台挖掘机在同一作用面机械开挖,挖掘机间距应大于( )。( B ) A、5m B...

  • JetPack WorkManager

    1.概览 官方文档:WorkManager 谷歌实验室:官方教程 官方案例:android-workmanager WorkManger介绍视频:中文官方介绍视频 谷歌工程师博客:https://medium.com/androiddevelopers/workmanager-basics-beba51e94048 Android JetPack实例学习:https://www.jiansh...

  • IntellIJ IDEA2020新功能

    一、java 1、Java 14支持:记录和模式匹配 IntelliJ IDEA 2020.1添加了对Java 14及其新功能的支持。IDE不仅添加了对Records的完整代码洞察支持,而且还使您能够快速创建新记录并生成其构造函数和组件,并警告存在的错误。您还将发现对instanceof运算符的模式匹配的支持,包括新的检查和快速修复,该快速修复通过用新的简洁模式变量替换它们来快速简化冗长的i...

  • SpringMVC学习--响应Ajax请求

    1.首先在webapp下新建一个js目录并导入jquery-3.5.1.min.js,然后在jsp页面中引入jquery Title 2.因为DispatcherServlet会拦截到所有的资源,导致我们的静态资源(img,css,js)也会被拦截,从而不能被使用,解决的方式就是配置静态资源不被拦截,在springmvc.xml中添加以下配置用来告诉DispatcherSe...

  • 尽量简单与简单的相对性

    简单的定义 什么叫复杂,没有做了没有必要的逻辑,达到目的有更简单的路线,比如下图: 尽量通过简单的办法来达到目的,技术本身并无优劣之分,关键是要识别面对当前场景的问题,分析出当中的痛点,选用合适的技术解决;比如上图中如果A和B之间直线有陷阱,有可能看似绕远的路径依然是最简单的路径。 应用一:简化需求 功能设计复杂了,不一定有收益,可能更不好用; 举个例子: 需求:平时我会在电脑上把不同的资料...

  • 前端路 - Webpack

    概述 本质 JavaScript 应用程序的静态模块打包器 核心 加载器(Loader)机制 工作流程 配置初始化 webpack 会首先读取配置文件,执行默认配置 编译前准备 webpack 会实例化 compiler,注册 plugins、resolverFactory、hooks。 reslove 前准备 webpack 实例化 compilation、NormalModuleFact...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。