序
在实际编程中,我们经常会遇到上传文件和显示上传进度的功能。为此,本文介绍了在不使用flash或任何插件上传文件的情况下,通过进度显示上传文件的功能。
基本功能:用进度条实现文件上传功能。
高级功能:通过拖拽文件实现多种文件上传功能。
背景
HTML5提供了访问本地文件的标准方法。——文件API规范。通过调用File API可以访问文件信息,客户端可以用来验证上传文件的类型和大小是否标准。
该规范包含以下使用该文件的接口:
文件接口:拥有文件的“读取权限”,可以获取文件名、类型、大小等。
FileList界面:指单独选择的文件列表,可以通过输入type='file '或拖拽的方式呈现在用户界面中,供用户选择。
XMLHTTPRequest2是HTML5的无名英雄。XHR2与xmlhttprequest基本相同,但它也增加了许多新功能,如下所示:
1.添加用于上传/下载的二进制数据。
2.在上传过程中增加了一个Progess事件,包含多部分信息:
Total:整数值,用于指定传输数据的总字节数。Loaded:一个整数值,用于指定上传的字节。lengthComputable:Bool值用于检测上传的文件大小是否可计算。
3.跨资源共享请求。
这些新特性让Ajax和html5配合得很好,让文件上传变得非常简单,不需要使用Flash Player、外部插件或者html表单标签就可以完成,上传进度条可以根据服务器显示。
本文将编写一个可以实现以下功能的小应用程序:
上传单个文件,并提供上传进度信息显示。向服务器发送图片时创建缩略图。通过文件列表或拖放操作上传多个文件。首先我们需要检查浏览器是否支持XHR2、File API、FormData和拖放操作。
写代码
如何上传单个文件并显示上传进度?
首先要做的是创建一个简单的视图:
定义由输入文件元素和提交按钮组成的表单。
使用引导进度条显示进度。
div id=' FormContent ' form id=' FormUpload ' enctype=' multipart/form-data ' method=' post ' span class=' BTN BTN-success file input-button ' I class=' glyphicon glyphicon-plus '/I span添加文件./span输入类型=' file ' name=' uploaded file ' id=' uploaded file '/span button class=' BTN BTN-primary start ' type=' button ' id=' Submit _ BTN ' I class=' glyphicon glyphicon-upload '/I span start uploaded file/span/button class=' BTN BTN-warning Cancel ' type=' button ' id=' Cancel _ BTN ' I class=' glyphicon-ban-circle '/I span close/span/button/form div class='span/span/Div/Div class=' info container ' Div id=' Imagecontainer '/Div Div id=' FileName ' class=' info '/Div Div id=' FileType ' class=' info '/Div id=' filesize ' class=' info '/Div/Div/Div在Onchange事件中添加输入文件元素,并在JS方法SingleFileSelected中使用它们,因此当用户选择和修改文件时将调用此方法。在这种方法中,我们将选择输入文件元素和访问文件列表的文件对象,并选择第一个文件文件[0],这样我们就可以获得文件名和文件类型等信息。
函数单个选定文件(evt){//var选定文件=evt。目标。文件可以使用这个或选择输入文件元素//,并访问它的文件对象var选择的文件=($(' #上传的文件')[].文件[];//文件控制。文件[];if(所选文件){ var FileSize=;var imageType=/image .*/;if(所选文件。大小){文件大小=数学。圆形(选定的文件。大小*/)/' MB ';} else if(所选文件。size){ FileSize=math。圆形(选定的文件。大小*/)/' KB ';} else { FileSize=选定的文件。大小“字节”;} //这里我们会添加上传图片缩略图预览的代码$('#FileName ').文本(“名称”选定的文件。名称);$('#FileType ').文本(“类型”选定的文件。类型);$('#FileSize ').文本("大小"文件大小);} }可以通过文件阅读器对象从内存读取上传文件内容读者。对象提供很多事件,onload,onError以及四种读取数据的函数readAsBinaryString()、readAsText()、readAsArrayBuffer()、readAsDataURL(),结果属性表示文件内容。该属性只有当读操作执行完成后才有效,数据格式根据调用的初始化读操作制定的。
在这里就不详细解释文件阅读器,我们会在单个文件选择方法中使用,用于预览图像,查看代码:
if(所选文件。打字。match(imageType)){ var reader=new file reader();读者。onload=函数(e){ $(' # Imagecontainer ').empty();var dataURL=reader . resultvar img=new Image()img。src=dataURLimg . NAmE=' thumb $(' # Imagecontainer ').追加(img);};读者。readasdataurl(选定的文件);}到现在为止,就可看到下图:
现在需要将已上传的文件发送到服务器,因此添加Onclick事件,并在JS uploadFile()方法中调用,代码如下:
函数UploadFile(){//我们可以通过将表单传递给表单数据对象的构造器或者使用附加函数手动创建它来创建表单//但是请注意文件名应该与操作参数//var dataString=new formData()一样;//数据字符串。追加('上传的文件',选择的文件);var form=$(' # FormUpload ')[];var dataString=新表单数据(表单);$.Ajax({ URL/' Uploader/Uploader ',//服务器脚本来处理数据类型' POST ',xhr函数(){//Custom XMLHttpRequest var myXhr=$。ajaxsettings。xhr();if (myXhr.upload) { //检查上传属性是否存在//myxhr。上传。on progress=ProgressHandlingFunction my xhr。上传。addeventlistener(' progress ',进度处理函数,false);//用于处理上传进度}返回myXhr}、//Ajax事件成功成功处理程序、错误处理程序、完成完成处理程序、/表单数据数据数据字符串、//选项告诉jQuery不要处理数据或者担心内容类型cache false,contentType false,process data false });}在该方法中,发送表单,使用形式数据对象来序列化文件值,我们可以手动创建表单数据数据的实例化,通过调用追加()方法将域值挂起,或是通过检索超文本标记语言表单的表单数据对象。
progressHandlingFunction方法会提供检验上传文件大小是否可计算,使用已加载和e。合计计算出已上传百分之多少的数据。
函数progress handling function(e){ if(e . length computed){ var percent complete=math。四舍五入(e . loaded */e . total);$('#FileProgress ').css('width ',percentComplete '% ').attr('aria-valuenow ',完成百分比);$(' #文件进度跨度').文本(百分比完成"%");} else { $('#FileProgress span ').文本("无法计算");} }现在已经实现了基本的发送数据及提供进度条的功能,接下来需要实现服务器端的代码处理,使用上传操作方法和上位控制器。
在上传方法中,可以从HttpPostedfileBase对象中获取文件信息,该对象包含上传的文件的基本信息如文件名属性,内容类型属性,输入流属性等内容,这些信息都可以用来验证服务器端接收的文件是否有错,也可以用来保存文件。
public JsonResult上传文件(https tedfile基础上传文件){ if(上传文件!=空上传文件.内容长度){ byte[]FileByteArray=新字节[上传的文件]。内容长度];上传文件。输入流。读取(文件字节数组,上传文件内容长度);附件新内容=新附件();新技术.文件名=上传文件。文件名;新技术.文件类型=上传文件内容类型新内容.文件内容=文件字节数组操作结果操作结果=附件管理器保存附件(新附件);if(操作结果.成功){ StrIng HTMl StrIng=captureHelper .renderviewtoststring(' _ AttachmentItem ',newAttchment,this .控制器上下文);返回Json(新{ statusCode=,status=operationResult .Message,NewRow=HTMLString },JsonRequestBehavior .允许get);} else { return Json(new { status code=,status=operationResult .消息,文件=上传文件FileName },JsonRequestBehavior .允许get);} }返回Json(新的{ statusCode=,状态='错误请求!"上传失败",文件=字符串。空},JsonRequestBehavior .允许get);}能否通过拖拽操作实现多个文件上传的功能?
在这一部分,实现相同的上传者,并为上传者添加一些新功能:
允许选择多个文件拖拽操作现在给上传者视图添加新功能:
为输入文件元素添加多个属性,实现同时选择多个文件。
添加实现拖拽功能的文件,如以下代码所示:
div id='drop_zone '将图像拖放到此处/div在射流研究…方法多文件选择中添加onChange事件,与之前单个文件选择的写法类似,不同的是需要将所有的文件列出,并允许拖拽文件。代码如下:
选择了函数multiplefile(evt){ evt。stopperpagation();evt。prevent default();$(“# drop _ zone”).removeClass(“”悬停');所选文件=evt。目标。文件| | evt。数据传输。文件;if(所选文件){ $(' # Files ')).empty();对于(var I=;我选择了文件长度;I){ dataurlfilereader。read(选中文件[I],函数(err,fileInfo) { if (err!=null){ var RowInfo=' div id=' File _ ' I ' ' class=' info ' div class=' info container ' ' ' div class=' err ' ' err '/div ' ' div data-name=' FileInfo。name/' div ' ' div data-type=' info ' ' FileType ' class=' info ' ' FileInfo。type '=info ' ' div data-size=' FileSize ' class=' info ' ' FileInfo。size()'/div/HR//div ';$(' #文件')。追加(RowInfo);} else { var image=' img src=' http : ' FileInfo。file content“”class=“thumb”title=“FileInfo”。名称' '/';var RowInfo=' div id=' File _ I ' I ' ' class=' info ' div class=' info container ' ' ' div data _ img=' image container ' ' image '/div ' ' div data-name=' FileInfo。name/' div ' ' div data-type=' info ' ' FileType ' class=' info ' ' FileInfo。size()'/div/div HR//div;$(' #文件')。追加(RowInfo);} });} } }在该方法中,将选择和拖拽文件操作的变量设置为全局变量选择文件,然后扫描选择的文件中的每个文件,将从DataURLreader对象中调用阅读方法读取文件。
DataURLreader对象可调用阅读方法,并将文件对象和回调方法作为阅读方法参数,在上述方法中我们创建了文件阅读器,并修改了文件阅读器的装载和onerror回调函数。调用readAsDataURL方法来读文件。
新建文件信息对象包括了所有的文件信息及内容。
var DataURLFileReader={ read函数(文件,回调){ var reader=new file reader();var fileInfo={ name file.name,type file.type,fileContent null,size function(){ var FileSize=;if(文件。size){ FileSize=math。圆形(文件。大小*/)/' MB ';} else if(文件。size){ FileSize=math。圆形(文件。大小*/)/' KB ';} else { FileSize=file。大小'字节';}返回文件大小} };if(!file.type.match('image .*){回调('不允许文件类型,FileInfo);返回;}读者。onload=function(){ FileInfo。文件内容=阅读器。结果;回调(null,FileInfo);};读者。one rror=function(){ callback(reader。错误,FileInfo);};reader.readAsDataURL(文件);} };使用拖拽操作选择
由于大部分浏览器现在已经执行拖拽操作,为了实现拖拽操作,在拖放区元素中添加拖挂和滴事件。
var DropZone=文档。GetElementByID(' DropZone ');DropZone。AddEventListener(' drag over ',handleDragOver,false);DropZone。AddEventListener(' Drop ',MultiplefileSelected,false);下降区。addeventlistener(' drag enter ',dragenterHandler,false);下降区。addeventlistener(' drag leave leave handler,false);
当文件拖到目标位置时触发拖挂事件,在以下代码中,我们修改了默认浏览器及数据传输的dropEffect属性,代码如下:
函数handleDragOver(evt){ evt。prevent default();evt。数据传输。允许的效果=“复制”;evt。数据传输。Dropeffect=' copy}接着在多文件选择中添加滴事件来处理文件滴操作。
大部分功能已经完善,现在需要添加"上传按钮",通过Onclick事件来调用上传多个文件方法。
该方法与上文提到的上传文件方法类似,不同的是手动验证表单数据对象值。
函数UploadMultipleFiles() { //这里我们将手动创建表单数据,以防止发送孟族人图像文件var dataString=new FormData();//var file=document。getelementbyid(' uploaded file ').文件;对于(var I=;我选择了文件长度;i ) { if(!选中的文件[I]。打字。匹配('图像.*){继续;} } //AJAX请求代码在这里}接下来添加服务器端处理代码,与上文添加的代码类似,需要做的就是接受一系列的文件列表,如下:
public JsonResult uplod multiple(httptedfilebase[]上传的文件)
确保HttpPostedFileBase数组名称与附加方法中的名称相同,只有这样,MVC才能映射到文件数组中。
公共JSON结果uplod多个(httpedfilebase[]上传的文件)数据字符串。追加('上传文件',选中文件[I]);
上传大文件
为了允许上传大文件,如果使用的是IIS7及以上版本,需要修改Web.config文件,添加以下代码:
系统。webserver安全请求过滤请求限制maxAllowedContentLength=' '//请求过滤/安全/系统。web server http runtimetargetframework=' ' MaxRequestLength=' '/到这里所有的功能就可以实现了,而且最大可上传2GB的文件。
以上内容就是小编给大家介绍的手动音量调节中基于埃阿斯和HTML5实现文件上传功能,希望对大家有所帮助。