Introduction
In the actual programming, often encountered to achieve file upload and display the upload progress of the function, based on this purpose, this article will introduce you do not use Flash or any upload file plug-ins to achieve with progress display file upload function.
Basic function: Implement file Upload function with progress bar
Advanced Features: The operation of dragging files to achieve multiple file upload function
Background
HTML5 provides a standard way to access local Files--file API specification, which enables you to access file information through the call file API, and to verify that the type and size of uploaded files are regulated by using the client side.
The specification includes the following interfaces to use the file:
File interface: Has Read permission for files, can get file name, type, size, etc.
FileList interface: Refers to a separately selected list of files, which can be presented in the user interface by <input type= "file" > or drag-and-drop for user selection.
XMLHTTPRequest2 is the unsung hero of HTML5, XHR2 is roughly the same as XMLHttpRequest, but has also added many new features, as follows:
1. Added upload/download binary data
2. Increased the progess (progress bar) event in the upload process, which contains a number of parts of the information:
Total: An integer value that specifies how many bytes of data to transmit.
Loaded: An integer value that specifies the bytes to upload.
The Lengthcomputable:bool value is used to detect whether the uploaded file size is computable.
3. Cross-resource sharing requests
These new features all make Ajax and HTML5 work well together, making file uploads very simple, no longer need to use flash Player, external plugins or HTML <form> tags to complete, according to the server side can display the upload progress bar.
This article will write a small application that can implement the following features:
Upload a single file, provide upload progress information display.
When you send a picture to the server, create an image thumbnail.
Multiple file uploads via file list or drag-and-drop operation.
First we need to check whether the browser supports Xhr2,file Api,formdata and drag-and-drop operations.
Writing code
How do I upload a single file and display the upload progress?
The first thing you need to do is create a simple view:
Defines a form that consists of an input file element and a submit button.
Use the bootstrap progress bar to display progress.
<div id= "Formcontent" > <form id= "formupload" enctype= "Multipart/form-data" method= "POST" > <span class= "btn btn-success Fileinput-button" > <i class= "Glyphicon glyphicon-plus" ></i&
Gt <span>add files...</span> <input type= "file" Name= "UploadedFile" id= "UploadedFile" /> </span> <button class= "btn btn-primary Start" type= "button" id= "Submit_btn" &G
T <i class= "Glyphicon glyphicon-upload" ></i> <span>start upload</span> </bu tton> <button class= "btn btn-warning Cancel" type= "button" id= "Cancel_btn" > <i
class= "Glyphicon glyphicon-ban-circle" ></i> <span>close</span> </button>
</form> <div class= "Progress customprogress" > <div id= "fileprogress" class= "Progress-bar" role= "ProgressBar" aria-valuenow= "" aria-valuemin= "" aria-valuemax= "" style= "width %;" > <span></span> </div> </div> <div class= "Infocontaine R "> <div id=" imagecontainer "></div> <div id=" FileName "class=" info "> &L t;/div> <div id= "FileType" class= "info" > </div> <div id= "FileSize" Info "> </div> </div> </div>
The
Adds an input file element to the OnChange event and is used in the JS method singlefileselected, so this method is called when the user selects and modifies the file. In this method, we will select the input file element and access the FileList file object, select the first file Files[0], so we can get the file name, file type and so on information.
function singlefileselected (evt) {//var selectedfile = evt.target.files can use thi s 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'll add the code of thumbnail preview of upload images $ ("#FileName"). Text ("Name" + Sele
Ctedfile.name);
$ ("#FileType"). Text ("type" + Selectedfile.type);
$ ("#FileSize"). Text ("Size" + FileSize); }
}
Upload file contents can be read from memory through the file reader object. The reader object provides many events, Onload,onerror, and four functions for reading data readasbinarystring (), Readastext (), Readasarraybuffer (), Readasdataurl (), The result property represents the contents of the file. This property is valid only if the read operation is completed, and the data format is based on the initialization read operation of the call.
The file reader is not explained in detail here, and we use it in the Singlefileselected method to preview the image and view the code:
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);
}
So far, you can see the following figure:
Now you need to send the uploaded file to the server, so add the onclick event and call it in the JS UploadFile () method, the code is as follows:
function UploadFile () {//we can create form by passing the form to constructor of FormData object//or G It manually using append function//but Please note file name should is 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 () {//Custo
M 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 isn't to process data or worry about cont
Ent-type.
Cache false, ContentType false, ProcessData false}); }
In this method, sending the form, using the form data object to serialize the file value, we can manually create an instantiation of the Formdata data, suspend the domain value by calling the Append () method, or retrieve the Formdata object of the HTML form.
The Progresshandlingfunction method provides a way to verify that the size of the uploaded file is computable, using e.loaded and e.total to calculate how much data has been uploaded.
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 ');
}
Now that you have the basic ability to send data and provide a progress bar, you need to implement server-side code processing, using the upload action method and the Uplpader controller.
In the upload method, you can obtain file information from the HttpPostedFileBase object that contains the basic information of the uploaded file such as the filename attribute, the contenttype attribute, the InputStream attribute, and so on. This information can be used to verify that the file received by the server is faulty or that it can be used to save the file.
Public Jsonresult Upload (HttpPostedFileBase uploadedfile) {if uploadedfile!= null && uploaded
File.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 ("_a Ttachmentitem ", Newattchment, this.
ControllerContext); Return Json (New {StatusCode =, status = Operationresult.message, N Ewrow = 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); }
Can I use drag-and-drop to implement multiple file upload functions?
In this section, implement the same uploader and add some new features for uploader:
Allow multiple files to be selected
Drag and drop operation
Now add new features to Uplodaer view:
Add multiple properties to the input file element to enable simultaneous selection of multiple files.
Add a file to implement drag-and-drop functionality, as shown in the following code:
<div id= "Drop_zone" >drop images here</div>
In the JS method multiplefileselected Add onchange event, similar to the previous singlefileselected, the difference is that all the files need to be listed, and allow dragging files. The code is as follows:
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 < selectedfiles.length i++) {dataurlfilereader.read (Selectedfiles[i], function (err, Filein FO) {if (err!= null) {var rowinfo = ' <div id= ' file_ ' + i + ' ' class= ' info ' ><
;d IV class= "Infocontainer" > ' + ' <div class= "Error" > ' err + ' </div> ' +
' <div data-name= ' FileName ' class= ' info ' > ' + fileinfo.name + ' </div> ' +
' <div data-type= "FileType" class= "info" > ' + fileinfo.type + ' </div> ' + ' <div data-size= "FileSize" class= "info" > ' + fileinfo.size () + ' </div& Gt;&lT;/div>
In this method, the variable that selects and drags the file action is set to the global variable selectedfiles, and then scans each file in SelectedFiles, and the Read method is invoked from the Dataurlreader object for reading the file.
The Dataurlreader object can call the Read method and use the file object and the callback method as the Read method parameter, in which we create the FileReader and modify the FileReader onload and OnError callback functions. Call the Readasdataurl method to read the file.
The new FileInfo object includes all the file information and content.
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); }
};
Use drag-and-drop operations to select
Because most browsers have now performed drag-and-drop operations, add dragover and drop events to the Drop_zone element in order to implement drag-and-drop operations.
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);
When the file is dragged to the target to trigger the DragOver event, in the following code we have modified the default browser and the DropEffect property of the DataTransfer, the code is as follows:
function Handledragover (evt) {
evt.preventdefault ();
evt.dataTransfer.effectAllowed = ' copy ';
Evt.dataTransfer.dropEffect = ' copy ';
}
The drop event is then added to the multiplefileselected to handle the file drop operation.
Most of the functionality has been perfected, and now you need to add the "upload button" to invoke the Uploadmultiplefiles method through the onclick event.
This method is similar to the UploadFile method mentioned above, and the difference is to manually validate the Formdata object value.
function Uploadmultiplefiles () {
//Here we'll create FormData manually to prevent sending Mon image files
var d atastring = new FormData ();
var files = document.getElementById ("Uploadedfiles"). Files;
for (var i =; i < selectedfiles.length; i++) {
if (!selectedfiles[i].type.match (' image.* ')) {
continue;
}
}
AJAX Request code here
}
Next, add server-side processing code, similar to the code added above, to accept a series of file lists, as follows:
Public Jsonresult uplodmultiple (httppostedfilebase[] uploadedfiles)
Make sure that the HttpPostedFileBase array name is the same as the name in the Append method, so that MVC can be mapped to a file array.
Public Jsonresult uplodmultiple (httppostedfilebase[] uploadedfiles)
Datastring.append ("Uploadedfiles", Selectedfiles[i]);
Uploading large files
To allow large files to be uploaded, if you are using IIS7 and above, you need to modify the Web.config file and add the following code:
<system.webServer>
<security>
<requestFiltering>
<requestlimits Maxallowedcontentlength= ""/>
</requestFiltering>
</security>
</system.webserver >
All the features are available here, and the maximum upload of 2GB files.
The above content is small make up to everybody introduce MVC and HTML5 implement file upload function, hope to be helpful to everybody.