利用Plupload.js解决大文件上传问题, 带进度条和背景遮罩层

前端之家收集整理的这篇文章主要介绍了利用Plupload.js解决大文件上传问题, 带进度条和背景遮罩层前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

大容量文件上传早已不是什么新鲜问题,在.net 2.0时代,HTML5也还没有问世,要实现这样的功能,要么是改web.config,要么是用flash,要么是用一些第三方控件,然而这些解决问题的方法要么很麻烦,比如改配置,要么不稳定,比如文件上G以后,上传要么死掉,要么卡住,通过设置web.config并不能很好的解决这些问题。

这是一个Html5统治浏览器的时代,在这个新的时代,这种问题已被简化并解决,我们可以利用Html5分片上传的技术,那么Plupload则是一个对此技术进行封装的前端脚本库,这个库的好处是可以自动检测浏览器是否支持html5技术,不支持再检测是否支持flash技术,甚至是sliverlight技术,如果支持,就使用检测到的技术。

那么这个库到哪里下载,怎么搭建呢,比较懒的童鞋还是用Install-Package Plupload搞定吧,一个命令搞定所有事

下面给出一个例子,使用自已定义的控件来使用Plupload (Plupload也有自己的界面可以用),如下

Plupload支持功能这里就不细说了,什么批量上传,这里我没有用到,主要是感觉它支持的事件非常丰富,文件选取后的事件,文件上传中的事件(可获得文件上传进度),文件上传成功的事件,文件上传失败的事件,等等

我的例子主要是上传一个单个文件,并显示上传的进度条(使用jQuery的一个进度条插件)

下面的例子主要是为文件上传交给 UploadCoursePackage.ashx 来处理

上传对象 var uploader = new plupload.Uploader({ browse_button: 'browse',//触发文件选择对话框的按钮,为那个元素id runtimes: 'html5,flash,silverlight,html4',//兼容的上传方式 url: "Handlers/UploadCoursePackage.ashx",//后端交互处理地址 max_retries: 3,//允许重试次数 chunk_size: '10mb',//分块大小 rename: true,//重命名 dragdrop: false,//允许拖拽文件进行上传 unique_names: true,//文件名称唯一性
    filters: { //过滤器
      max_file_size: '999999999mb',//<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a>最大尺寸
      mime_types: [ //允许<a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>的<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a>类型
        { title: "Zip",extensions: "zip" },{ title: "PE",extensions: "pe" }
      ]
    },//<a href="/tag/zidingyi/" target="_blank" class="keywords">自定义</a>参数 (键值对形式) 此处可以定义参数
    multipart_params: {
      type: "misoft"
    },// FLASH的配置
    flash_swf_url: "../Scripts/plupload/Moxie.swf",// Silverligh的配置
    silverlight_xap_url: "../Scripts/plupload/Moxie.xap",multi_selection: false //true:ctrl多<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a><a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>,false 单<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a><a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a> 
  });

  //在实例对象上<a href="/tag/diaoyong/" target="_blank" class="keywords">调用</a>init()<a href="/tag/fangfa/" target="_blank" class="keywords">方法</a>进行初始化
  uploader.init();

  uploader.bind('FilesAdded',function (uploader,files) {
    $("#<%=fileSource.ClientID %>").val(files[0].name);
    $.ajax(
    {
      type: 'post',url: 'HardDiskSpace.aspx/GetHardDiskFreeSpace',data: {},dataType: 'json',contentType: 'application/json;charset=utf-8',success: function (result) {
        //选择<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a>以后检测服务器剩余磁盘空间是否够用
        if (files.length > 0) {
          if (parseInt(files[0].size) > parseInt(result.d)) {
            $('#error-msg').text("<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a>容量大于剩余磁盘空间,请联系<a href="/tag/guanliyuan/" target="_blank" class="keywords">管理员</a>!");
          } else {
            $('#error-msg').text("");
          }
        }
      },error: function(xhr,err,obj) {
        $('#error-msg').text("检测服务器剩余磁盘空间失败");
      }
    });
  });

  uploader.bind('UploadProgress',file) {
    var percent = file.percent;
    progressBar.progress(percent);
  });

  uploader.bind('FileUploaded',function (up,file,callBack) {
    var data = $.parseJSON(callBack.response);
    if (data.statusCode === "1") {
      $("#<%=hfPackagePath.ClientID %>").val(data.filePath);
      var id = $("#<%=hfCourseID.ClientID %>").val();
      __doPostBack("save",id);
    } else {
      hideLoading();
      $('#error-msg').text(data.message);
    }
  });

  uploader.bind('Error',err) {
    alert("<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a><a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>失败,<a href="/tag/cuowu/" target="_blank" class="keywords">错误</a>信息: " + err.message);
  });

后台 UploadCoursePackage.ashx 的代码也重要,主要是文件分片跟不分片的处理方式不一样

namespace WebUI.Handlers
{
///
/// UploadCoursePackage 的摘要说明
///

public class UploadCoursePackage : IHttpHandler
{

public void ProcessRequest(HttpContext context)
{
  context.Response.ContentType = "text/plain";

  int statuscode = 1;
  string message = string.Empty;
  string filepath = string.Empty;

  if (context.Request.Files.Count > 0)
  {
    try
    {
      string resourceDirectoryName = System.Configuration.ConfigurationManager.AppSettings["resourceDirectory"];
      string path = context.Server.MapPath("~/" + resourceDirectoryName);
      if (!Directory.Exists(path))
        Directory.CreateDirectory(path);

      int chunk = context.Request.Params["chunk"] != null ? int.Parse(context.Request.Params["chunk"]) : 0; //<a href="/tag/huoqu/" target="_blank" class="keywords">获取</a>当前的块ID,如果不是分块<a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>的。chunk则为0
      string fileName = context.Request.Params["name"]; //这里写的比较潦草。判断<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a>名是否为空。
      string type = context.Request.Params["type"]; //在前面JS中不是定义了<a href="/tag/zidingyi/" target="_blank" class="keywords">自定义</a>参数multipart_params的值么。其中有个值是type:"misoft",此处就可以<a href="/tag/huoqu/" target="_blank" class="keywords">获取</a>到这个值了。<a href="/tag/huoqu/" target="_blank" class="keywords">获取</a>到的type="misoft";

      string ext = Path.GetExtension(fileName);
      //fileName = string.Format("{0}{1}",Guid.NewGuid().ToString(),ext);
      filepath = resourceDirectoryName + "/" + fileName;
      fileName = Path.Combine(path,fileName);

      //对<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a>流进行存储 需要注意的是 files目录必须存在(此处可以做个判断) 根据上面的chunk来判断是块<a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>还是普通<a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a> <a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>方式不一样 ,导致的保存方式也会不一样
      FileStream fs = new FileStream(fileName,chunk == 0 ? FileMode.OpenOrCreate : FileMode.Append);
      //write our input stream to a buffer
      Byte[] buffer = null;
      if (context.Request.ContentType == "application/octet-stream" && context.Request.ContentLength > 0)
      {
        buffer = new Byte[context.Request.InputStream.Length];
        context.Request.InputStream.Read(buffer,buffer.Length);
      }
      else if (context.Request.ContentType.Contains("multipart/form-data") && context.Request.Files.Count > 0 && context.Request.Files[0].ContentLength > 0)
      {
        buffer = new Byte[context.Request.Files[0].InputStream.Length];
        context.Request.Files[0].InputStream.Read(buffer,buffer.Length);
      }

      //write the buffer to a file.
      if (buffer != null)
        fs.Write(buffer,buffer.Length);
      fs.Close();

      statuscode = 1;
      message = "<a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>成功";

    }
    catch (Exception ex)
    {
      statuscode = -1001;
      message = "保存时发生<a href="/tag/cuowu/" target="_blank" class="keywords">错误</a>,请确保<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a>有效且格式正确";

      Util.LogHelper logger = new Util.LogHelper();
      string path = context.Server.MapPath("~/Logs");
      logger.WriteLog(ex.Message,path);
    }
  }
  else
  {
    statuscode = -<a href="/tag/404/" target="_blank" class="keywords">404</a>;
    message = "<a href="/tag/shangchuan/" target="_blank" class="keywords">上传</a>失败,未接收到资源<a href="/tag/wenjian/" target="_blank" class="keywords">文件</a>";
  }

  string msg = "{\"statusCode\":\"" + statuscode + "\",\"message\":\"" + message + "\",\"filePath\":\"" + filepath + "\"}";
  context.Response.Write(msg);
}

public bool IsReusable
{
  get
  {
    return false;
  }
}

}
}

再附送一个检测服务器端硬盘剩余空间的功能

namespace WebUI
{
public partial class CheckHardDiskFreeSpace : System.Web.UI.Page
{
protected void Page_Load(object sender,EventArgs e)
{

}

/// <summary>
/// <a href="/tag/huoqu/" target="_blank" class="keywords">获取</a>磁盘剩余容量
/// </summary>
/// <returns></returns>
[WebMethod]
public static string GetHardDiskFreeSpace()
{
  const string strHardDiskName = @"F:\";

  var freeSpace = string.Empty;
  var drives = DriveInfo.GetDrives();
  var myDrive = (from drive in drives
    where drive.Name == strHardDiskName
    select drive).FirstOrDefault();
  if (myDrive != null)
  {
    freeSpace = myDrive.TotalFreeSpace+""; 
  }
  return freeSpace;
}

}
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

猜你在找的JavaScript相关文章