MVC中基于Ajax和HTML5实现文件上传功能

这篇文章主要介绍了mvc中基于ajaxhtml5实现文件上传功能的相关资料,需要的朋友可以参考下

引言

在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能。

基本功能:实现带有进度条的文件上传功能

高级功能:通过拖拽文件的操作实现多个文件上传功能

立即学习“前端免费学习笔记(深入)”;

背景

HTML5提供了一种标准的访问本地文件的方法——File API规格说明,通过调用File API 能够访问文件信息,也可以利用客户端来验证上传文件的类型和大小是否规范。

该规格说明包含以下几个接口来使用文件:

File接口:具有文件的“读权限”,可以获取文件名,类型,大小等。

FileList接口:指单独选定的文件列表,可以通过或拖拽呈现在用户界面供用户选择。

XMLHTTPRequest2是HTML5的无名英雄,XHR2与XMLHttpRequest大体相同,但同时也添加了很多新功能,如下:

1. 增加了上传/下载二进制数据

2. 增加了上传过程中Progess (进度条)事件,该事件包含多部分的信息:

Total:整型值,用于指定传输数据的总字节数。
Loaded:整型值,用于指定上传的字节。
lengthComputable:Bool值用于检测上传文件大小是否可计算。

3. 跨资源共享请求

这些新特性都使得Ajax和HTML5很好的协作,让文件上传变得非常简单,不再需要使用Flash Player、外部插件或html的

        

          

                      

                

          

          

          

          

          

          

          

              

在Onchange 事件中添加输入文件元素,并在JS方法SingleFileSelected使用,因此在用户选择和修改文件时都会调用此方法。在该方法中,我们将选择输入文件元素和访问FileList的文件对象,选择第一个文件files[0],因此我们可以得到文件名,文件类型等信息。

 function singleFileSelected(evt) {     //var selectedFile = evt.target.files can use this or select input file element      //and access it's files object     var selectedFile = ($("#UploadedFile"))[].files[];//FileControl.files[];     if (selectedFile) {       var FileSize = ;       var imageType = /image.*/;       if (selectedFile.size > ) {         FileSize = Math.round(selectedFile.size * / ) / + " MB";      }      else if (selectedFile.size > ) {        FileSize = Math.round(selectedFile.size * / ) / + " KB";      }      else {        FileSize = selectedFile.size + " Bytes";      }      // here we will add the code of thumbnail preview of upload images            $("#FileName").text("Name " + selectedFile.name);      $("#FileType").text("type " + selectedFile.type);      $("#FileSize").text("Size " + FileSize);    }  }

登录后复制

可以通过File reader对象从内存读取上传文件内容。reader 对象提供很多事件,onload,onError以及四种读取数据的函数readAsBinaryString(), readAsText(),readAsArrayBuffer(), readAsDataURL(),result属性表示文件内容。该属性只有当读操作执行完成后才有效,数据格式根据调用的初始化读操作制定的。

在这里就不详细解释File reader,我们会在SingleFileSelected 方法中使用,用于预览图像,查看代码:

 if (selectedFile.type.match(imageType)) {        var reader = new FileReader();        reader.onload = function (e) {          $("#Imagecontainer").empty();          var dataURL = reader.result;          var img = new Image()          img.src = dataURL;          img.className = "thumb";          $("#Imagecontainer").append(img);        };        reader.readAsDataURL(selectedFile);      }

登录后复制

到现在为止,就可看到下图:

MVC中基于Ajax和HTML5实现文件上传功能

现在需要将已上传的文件发送到服务器,因此添加Onclick事件,并在JS uploadFile()方法中调用,代码如下:

function UploadFile() {     //we can create form by passing the form to Constructor of formData object     //or creating it manually using append function      //but please note file name should be same like the action Parameter     //var dataString = new FormData();     //dataString.append("UploadedFile", selectedFile);        var form = $('#FormUpload')[];     var dataString = new FormData(form);    $.ajax({      url '/Uploader/Upload', //Server script to process data      type 'POST',      xhr function () { // Custom XMLHttpRequest        var myXhr = $.ajaxSettings.xhr();        if (myXhr.upload) { // Check if upload property exists          //myXhr.upload.onprogress = progressHandlingFunction          myXhr.upload.addEventListener('progress', progressHandlingFunction,           false); // For handling the progress of the upload        }        return myXhr;      },      //Ajax events      success successHandler,      error errorHandler,      completecompleteHandler,      // Form data      data dataString,      //Options to tell jQuery not to process data or worry about content-type.      cache false,      contentType false,      processData false    });  }

登录后复制

在该方法中,发送表单,使用Form 数据对象来序列化文件值,我们可以手动创建formdata数据的实例化,通过调用append()方法将域值挂起,或是通过检索HTML 表单的FormData对象。

progressHandlingFunction方法会提供检验上传文件Size 是否可计算,使用e.loaded和e.total计算出已上传百分之多少的数据。

function progressHandlingFunction(e) {     if (e.lengthComputable) {       var percentComplete = Math.round(e.loaded * / e.total);       $("#FileProgress").css("width",        percentComplete + '%').attr('aria-valuenow', percentComplete);       $('#FileProgress span').text(percentComplete + "%");     }     else {       $('#FileProgress span').text('unable to compute');    }  }

登录后复制

现在已经实现了基本的发送数据及提供进度条的功能,接下来需要实现服务器端的代码处理,使用upload action方法和uplpader controller 。

在upload 方法中,可以从HttpPostedfileBase对象中获取文件信息,该对象包含上传的文件的基本信息如Filename属性,Contenttype属性,inputStream属性等内容,这些信息都可以用来验证服务器端接收的文件是否有错,也可以用来保存文件。        

 public JsonResult Upload(HttpPostedFileBase uploadedFile)       {         if (uploadedFile != null && uploadedFile.ContentLength > )         {           byte[] FileByteArray = new byte[uploadedFile.ContentLength];           uploadedFile.InputStream.Read(FileByteArray, , uploadedFile.ContentLength);           Attachment newAttchment = new Attachment();          newAttchment.FileName = uploadedFile.FileName;          newAttchment.FileType = uploadedFile.ContentType;          newAttchment.FileContent = FileByteArray;          OperationResult operationResult = attachmentManager.SaveAttachment(newAttchment);          if (operationResult.Success)          {            string HTMLString = CaptureHelper.RenderViewToString            ("_AttachmentItem", newAttchment, this.ControllerContext);            return Json(new            {              statusCode = ,              status = operationResult.Message,              NewRow = HTMLString            }, JsonRequestBehavior.AllowGet);          }          else          {            return Json(new            {              statusCode = ,              status = operationResult.Message,              file = uploadedFile.FileName            }, JsonRequestBehavior.AllowGet);          }        }        return Json(new        {          statusCode = ,          status = "Bad Request! Upload Failed",          file = string.Empty        }, JsonRequestBehavior.AllowGet);      }

登录后复制

 能否通过拖拽操作实现多个文件上传的功能?

在这一部分,实现相同的uploader,并为uploader添加一些新功能:

允许选择多个文件
拖拽操作
现在给Uplodaer View添加新功能:

为输入文件元素添加多个属性,实现同时选择多个文件。

添加实现拖拽功能的文件,如以下代码所示:

 

Drop images Here

登录后复制

在JS方法MultiplefileSelected中添加onChange事件,与之前SingleFileSelected的写法类似,不同的是需要将所有的文件列出,并允许拖拽文件。代码如下:

 function MultiplefileSelected(evt) {     evt.stopPropagation();     evt.preventDefault();     $('#drop_zone').removeClass('hover');     selectedFiles = evt.target.files || evt.dataTransfer.files;     if (selectedFiles) {       $('#Files').empty();       for (var i = ; i 

' +                    '

' + err + '

' +                   '

' + fileInfo.name + '

' +                   '

' + fileInfo.type + '

' +                   '

' + fileInfo.size() +                    '


';            $('#Files').append(RowInfo);          }          else {            var image = 'MVC中基于Ajax和HTML5实现文件上传功能';            var RowInfo = '

' +                   '

' +                    image + '

' +                   '

' + fileInfo.name + '

' +                   '

' + fileInfo.type + '

' +                   '

' + fileInfo.size() +                    '


';            $('#Files').append(RowInfo);          }        });      }    }  }

登录后复制

在该方法中,将选择和拖拽文件操作的变量设置为全局变量selectedFiles,然后扫描 selectedfiles中的每个文件,将从 DataURLreader对象中调用Read 方法读取文件。

DataURLreader对象可调用read方法,并将File对象和回调方法作为read方法参数,在上述方法中我们创建了FileReader,并修改了FileReader的Onload和onerror回调函数。调用 readAsDataURL 方法来读文件。

新建FileInfo对象包括了所有的文件信息及内容。

 var DataURLFileReader = {     read function (file, callback) {       var reader = new FileReader();       var fileInfo = {         name file.name,         type file.type,         fileContent null,         size function () {           var FileSize = ;          if (file.size > ) {            FileSize = Math.round(file.size * / ) / + " MB";          }          else if (file.size > ) {            FileSize = Math.round(file.size * / ) / + " KB";          }          else {            FileSize = file.size + " bytes";          }          return FileSize;        }      };      if (!file.type.match('image.*')) {        callback("file type not allowed", fileInfo);        return;      }      reader.onload = function () {        fileInfo.fileContent = reader.result;        callback(null, fileInfo);      };      reader.onerror = function () {        callback(reader.error, fileInfo);      };      reader.readAsDataURL(file);    }  };

登录后复制

使用拖拽操作选择

由于大部分浏览器现在已经执行拖拽操作,为了实现拖拽操作,在drop_zone 元素中添加dragover和drop事件。

         var dropZone = document.getElementById(‘drop_zone’);
         dropZone.addEventListener(‘dragover’, handleDragOver, false);
         dropZone.addEventListener(‘drop’, MultiplefileSelected, false);
         dropZone.addEventListener(‘dragenter’, dragenterHandler, false);
         dropZone.addEventListener(‘dragleave’, dragleaveHandler, false);

当文件拖到目标位置时触发dragover事件,在以下代码中,我们修改了默认浏览器及datatransfer的dropEffect 属性,代码如下:

  function handleDragOver(evt) {     evt.preventDefault();     evt.dataTransfer.effectAllowed = 'copy';     evt.dataTransfer.dropEffect = 'copy';   }

登录后复制

接着在MultiplefileSelected中添加drop事件来处理文件drop操作。

大部分功能已经完善,现在需要添加“上传按钮”,通过Onclick事件来调用UploadMultipleFiles方法。

该方法与上文提到的Uploadfile方法类似,不同的是手动验证formdata对象值。

   function UploadMultipleFiles() {     // here we will create FormData manually to prevent sending mon image files     var dataString = new FormData();     //var files = document.getElementById("UploadedFiles").files;     for (var i = ; i 

接下来添加服务器端处理代码,与上文添加的代码类似,需要做的就是接受一系列的文件列表,如下:

  public JsonResult UplodMultiple(HttpPostedFileBase[] uploadedFiles)

确保 HttpPostedFileBase 数组名称与append 方法中的名称相同,只有这样,MVC才能映射到文件数组中。

 public JsonResult UplodMultiple(HttpPostedFileBase[] uploadedFiles)
  dataString.append("uploadedFiles", selectedFiles[i]); 

上传大文件

为了允许上传大文件,如果使用的是 IIS7及以上版本,需要修改Web.config 文件,添加以下代码:

                                                        

登录后复制

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

初步了解JavaScript,Ajax,jQuery,并比较三者关系

jquery与php结合实现AJAX长轮询

js ajax加载时的进度条代码

以上就是MVC中基于Ajax和HTML5实现文件上传功能的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2757780.html

(0)
上一篇 2025年3月8日 08:00:45
下一篇 2025年3月8日 08:00:54

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论