webuploader的使用

WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又 不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。采用大文件分片并发上传,极大的提高了文件上传效率。

最近做两个项目均使用到。接口简单,引用资源也不多

// 图片上传demo
jQuery(function() {
    var $ = jQuery,
        $list = $('#fileList'),
        // 优化retina, 在retina下这个值是2
        ratio = window.devicePixelRatio || 1,

        // 缩略图大小
        thumbnailWidth = 100 * ratio,
        thumbnailHeight = 100 * ratio,

        // Web Uploader实例
        uploader;

    // 初始化Web Uploader
    uploader = WebUploader.create({

        // 自动上传。
        auto: true,

        // swf文件路径
        swf: BASE_URL + '/js/Uploader.swf',

        // 文件接收服务端。
        server: 'http://webuploader.duapp.com/server/fileupload.php',

        // 选择文件的按钮。可选。
        // 内部根据当前运行是创建,可能是input元素,也可能是flash.
        pick: '#filePicker',

        // 只允许选择文件,可选。
        accept: {
            title: 'Images',
            extensions: 'gif,jpg,jpeg,bmp,png',
            mimeTypes: 'image/*'
        }
    });

    // 当有文件添加进来的时候
    uploader.on( 'fileQueued', function( file ) {
        var $li = $(
                '<div id="' + file.id + '" class="file-item thumbnail">' +
                    '<img>' +
                    '<div class="info">' + file.name + '</div>' +
                '</div>'
                ),
            $img = $li.find('img');

        $list.append( $li );

        // 创建缩略图
        uploader.makeThumb( file, function( error, src ) {
            if ( error ) {
                $img.replaceWith('<span>不能预览</span>');
                return;
            }

            $img.attr( 'src', src );
        }, thumbnailWidth, thumbnailHeight );
    });

    // 文件上传过程中创建进度条实时显示。
    uploader.on( 'uploadProgress', function( file, percentage ) {
        var $li = $( '#'+file.id ),
            $percent = $li.find('.progress span');

        // 避免重复创建
        if ( !$percent.length ) {
            $percent = $('<p class="progress"><span></span></p>')
                    .appendTo( $li )
                    .find('span');
        }

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

    // 文件上传成功,给item添加成功class, 用样式标记上传成功。
    uploader.on( 'uploadSuccess', function( file ) {
        $( '#'+file.id ).addClass('upload-state-done');
    });

    // 文件上传失败,现实上传出错。
    uploader.on( 'uploadError', function( file ) {
        var $li = $( '#'+file.id ),
            $error = $li.find('div.error');

        // 避免重复创建
        if ( !$error.length ) {
            $error = $('<div class="error"></div>').appendTo( $li );
        }

        $error.text('上传失败');
    });

    // 完成上传完了,成功或者失败,先删除进度条。
    uploader.on( 'uploadComplete', function( file ) {
        $( '#'+file.id ).find('.progress').remove();
    });
});

这个开发团队很大,遇到问题,上github很快就回复了。

 

 

webuploader官方地址 http://fex-team.github.io/webuploader/

 

 

双核浏览器下在chrome内核中使用uploadify总有302问题,也不知道如何修复,之所以喜欢360浏览器是因为帮客户控制渲染内核:

若页面需默认用极速核,增加标签:<meta name="renderer" content="webkit"/> 
 若页面需默认用ie兼容内核,增加标签:<meta name="renderer" content="ie-comp"/> 
 若页面需默认用ie标准内核,增加标签:<meta name="renderer" content="ie-stand"/>

 

 要解决302问题也很简单,就是html5的文件上传,正好最近在ueditor里看到百度的webuploader,会自动选择flash html5,就是一个成熟的解决方案了。

 

先看前端,我们将最常用的操作封装为插件,asp.net中和MVC中最好使用相对于应用程序的绝对路径,自行定义全局 applicationPath :var applicationPath = "@(Href("~")=="/"?"":Href("~"))"; 

前端插件代码:

 

 

(function ($, window) {
    var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "../..";
    function S4() {
      return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    }

    function initWebUpload(item, options) {
    
        if (!WebUploader.Uploader.support()) {
            var error = "上传控件不支持您的浏览器!请尝试升级flash版本或者使用Chrome引擎的浏览器。<a target='_blank' href='http://se.360.cn'>下载页面</a>";
            if (window.console) {
                window.console.log(error);
            }
            $(item).text(error);
            return;
        }
    
        var defaults = {
            hiddenInputId: "uploadifyHiddenInputId", // input hidden id
            onAllComplete: function (event) { }, // 当所有file都上传后执行的回调函数
            onComplete: function (event) { },// 每上传一个file的回调函数
            innerOptions: {},
            fileNumLimit: undefined,
            fileSizeLimit: undefined,
            fileSingleSizeLimit: undefined,
            PostbackHold: false
        };
 
        var opts = $.extend({}, defaults, options);
        var hdFileData = $("#" + opts.hiddenInputId);
 
        var target = $(item);//容器
        var pickerid = "";
        if (typeof guidGenerator36 != 'undefined')//给一个唯一ID
            pickerid = guidGenerator36();
        else
            pickerid = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
 
        var uploaderStrdiv = '<div class="webuploader">' +
            '<div id="thelist" class="uploader-list"></div>' +
            '<div class="btns">' +
            '<div id="' + pickerid + '">选择文件</div>' +
            //'<a id="ctlBtn" class="btn btn-default">开始上传</a>' +
            '</div>' +
        '</div>';
        target.append(uploaderStrdiv);
 
        var $list = target.find('#thelist'),
             $btn = target.find('#ctlBtn'),//这个留着,以便随时切换是否要手动上传
             state = 'pending',
             uploader;
 
        var jsonData = {
            fileList: []
        };
 
        var webuploaderoptions = $.extend({
 
            // swf文件路径
            swf: applicationPath + '/Scripts/lib/webuploader/Uploader.swf',
 
            // 文件接收服务端。
            server: applicationPath + '/MvcPages/WebUploader/Process',
 
            // 选择文件的按钮。可选。
            // 内部根据当前运行是创建,可能是input元素,也可能是flash.
            pick: '#' + pickerid,
 
            // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
            resize: false,
            fileNumLimit: opts.fileNumLimit,
            fileSizeLimit: opts.fileSizeLimit,
            fileSingleSizeLimit: opts.fileSingleSizeLimit
        },
        opts.innerOptions);
        var uploader = WebUploader.create(webuploaderoptions);
 
      //回发时还原hiddenfiled的保持数据
      var fileDataStr = hdFileData.val();
      if (fileDataStr && opts.PostbackHold) {
        jsonData = JSON.parse(fileDataStr);
      $.each(jsonData.fileList, function (index, fileData) {
      var newid = S4();
      fileData.queueId = newid;
      $list.append('<div id="' + newid + '" class="item">' +
        '<div class="info">' + fileData.name + '</div>' +
        '<div class="state">已上传</div>' +
        '<div class="del"></div>' +
        '</div>');
      });
      hdFileData.val(JSON.stringify(jsonData));
      }




        uploader.on('fileQueued', function (file) {//队列事件
            $list.append('<div id="' + file.id + '" class="item">' +
                '<div class="info">' + file.name + '</div>' +
                '<div class="state">等待上传...</div>' +
                '<div class="del"></div>' +
            '</div>');
        });
        uploader.on('uploadProgress', function (file, percentage) {//进度条事件
            var $li = target.find('#' + file.id),
                $percent = $li.find('.progress .bar');
 
            // 避免重复创建
            if (!$percent.length) {
                $percent = $('<span class="progress">' +
                    '<span  class="percentage"><span class="text"></span>' +
                  '<span class="bar" role="progressbar" style="width: 0%">' +
                  '</span></span>' +
                '</span>').appendTo($li).find('.bar');
            }
 
            $li.find('div.state').text('上传中');
            $li.find(".text").text(Math.round(percentage * 100) + '%');
            $percent.css('width', percentage * 100 + '%');
        });
        uploader.on('uploadSuccess', function (file, response) {//上传成功事件
            target.find('#' + file.id).find('div.state').text('已上传');
            var fileEvent = {
                queueId: file.id,
                name: file.name,
                size: file.size,
                type: file.type,
                filePath: response.filePath
            };
            jsonData.fileList.push(fileEvent)
            opts.onComplete(fileEvent);
 
        });
 
        uploader.on('uploadError', function (file) {
            target.find('#' + file.id).find('div.state').text('上传出错');
        });
 
        uploader.on('uploadComplete', function (file) {//全部完成事件
            target.find('#' + file.id).find('.progress').fadeOut();
            var fp = $("#" + opts.hiddenInputId);
            fp.val(JSON.stringify(jsonData));
            opts.onAllComplete(jsonData.fileList);
        });
 
        uploader.on('fileQueued', function (file) {
            uploader.upload();
        });
 
        uploader.on('filesQueued', function (file) {
            uploader.upload();
        });
 
        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();
            }
        });
        //删除
        $list.on("click", ".del", function () {
            var $ele = $(this);
            var id = $ele.parent().attr("id");
            var deletefile = {};
            $.each(jsonData.fileList, function (index, item) {
                if (item && item.queueId === id) {
              uploader.removeFile(uploader.getFile(id));//不要遗漏
                    deletefile = jsonData.fileList.splice(index, 1)[0];
                    $("#" + opts.hiddenInputId).val(JSON.stringify(jsonData));
                    $.post(applicationi + "/Webploader/Delete", {  'filepathname': deletefile.filePath }, function (returndata) {
                        $ele.parent().remove();
                    });
                    return;
                }
            });
        });
 
    }
 
 
    $.fn.powerWebUpload = function (options) {
        var ele = this;
        if (typeof PowerJs != 'undefined') {
            $.lazyLoad(applicationPath + "/Scripts/lib/webuploader/webuploader.css", function () { }, 'css');
            $.lazyLoad(applicationPath + "/Scripts/lib/webuploader/webuploader.min.js", function () {
                initWebUpload(ele, options);
            });
        }
        else {
            initWebUpload(ele, options);
        }
    }
})(jQuery, window);

 

 

 

页面引入上述js后使用:

 $("#uploader").powerWebUpload({ hiddenInputId: "uploadhidden" }); 

html端需要一个容器和hidden

<div id="uploader"></div>
<asp:HiddenField ID="hfFilePath" ClientIDMode="Static" runat="server" />

 

 

MVC版后端文件接收,即便你是asp.net 引入mvc做ajax也是可以的:

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
public class WebUploaderController : BaseController
    {
        public ActionResult Process(string id, string name, string type, string lastModifiedDate, int size, HttpPostedFileBase file)
        {
            string filePathName = string.Empty;string localPath = Path.Combine(HttpRuntime.AppDomainAppPath, "Upload\\Document");
            if (Request.Files.Count == 0)
            {
                return Json(new { jsonrpc = 2.0, error = new { code = 102, message = "保存失败" }, id = "id" });
            }
            try
            {
                filePathName = //自己在这里处理文件保存并返回需要保存到hidden的数据,文件在file或者Request.Files[0]
            }
            catch (Exception)
            {
                return Json(new { jsonrpc = 2.0, error = new { code = 103, message = "保存失败" }, id = "id" });
            }

            return Json(new
            {
                jsonrpc = "2.0",
                id = "id",
                filePath = urlPath + "/" + filePathName
            });
        }

     static string urlPath = "../../Upload/Document";

 
        public ActionResult Delete(string filePathName)
        {
            if (string.IsNullOrEmpty(filePathName))
            {
                return Content("no");
            }
            //为了安全 检查一下路径 不够严谨 自行更具业务做更加细致的判断
            if (!filePathName.StartsWith(urlPath) ||
                filePathName.Substring(6, filePathName.Length - 7).Contains("../"))
            {
                return Content("no!");
            }
            string localFilePathName = this.Server.MapPath(filePathName);
 
            try
            {
                bool b = UploadifyManager.DeleteAttachment(localFilePathName);
                if (!b) throw new Exception("删除文件失败");
 
                return Content("ok");
            }
            catch
            {
                return Content("no");
            }
        }
    }

 

 

 完整demo: http://yunpan.cn/cgifFwGhbGSvi  提取码 f7c1

 

补充:

扩展自定义参数,利用uploadBeforeSend事件可以扩展参数,插件内可根据需要修改。

cookie的问题,我用微软自带的登录系统,不需要做任何特殊处理完全没有问题。

转载于:https://my.oschina.net/u/2558718/blog/743776

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值