Home>

introduction

In actual programming,I often encounter the function of uploading files and displaying upload progress.For this purpose,This article will introduce the file upload function with progress display without using flash or any plug-in for uploading files.

Basic function:implement file upload function with progress bar

Advanced features:Multiple file uploads via drag and drop

background

html5 provides a standard way to access local files-file api specifications,File information can be accessed by calling the file api,You can also use the client to verify the type and size of the uploaded file.

This specification contains the following interfaces to use the file:

file interface:has "read permissions" for a file, can get the file name,Type, size, etc.

filelist interface:refers to a list of individually selected files,It can be displayed in the user interface for selection byor drag and drop.

xmlhttprequest2 is the unknown hero of html5,xhr2 is roughly the same as xmlhttprequest,But also added many new features,as follows:

1. Added upload/download binary data

2. Added the progess (progress bar) event during the upload process, which contains multiple parts of information:

total:an integer value that specifies the total number of bytes of data to be transmitted.

loaded:an integer value that specifies the bytes to upload.

lengthcomputable:The bool value is used to detect whether the uploaded file size can be calculated.

3. Cross-resource sharing request

These new features make ajax and html5 work well together.Makes file upload very easy,No longer need to use flash player, external plugin or html's

tag to complete,The upload progress bar can be displayed according to the server.

This article will write a small application,Can achieve the following functions:

Upload a single file,Provide upload progress information display.

When sending pictures to the server,Create image thumbnails.

Upload multiple files through file list or drag operation.

First we need to check whether the browser supports xhr2, file api, formdata and drag and drop operations.

Write code

How to upload a single file and display the upload progress?

The first thing to do is to create a simple view:

Define a form,Consists of an input file element and a submit button.

Use the bootstrap progress bar to show progress.

<div>
        <form
        enctype="multipart/form-data" method="post">
          <span>
            <i></i>
            <span>add files ...</span>
            <input type="file"
            name="uploadedfile" />
          </span>
          <button
          type="button">
            <i></i>
            <span>start upload</span>
          </button>
          <button
          type="button">
            <i></i>
            <span>close</span>
          </button>
        </form>
        <div>
          <div
          role="progressbar"
      aria-valuenow="" aria-valuemin=""
      aria-valuemax="">
            <span></span>
          </div>
        </div>
        <div>
          <div></div>
          <div>
          </div>
          <div>
          </div>
          <div>
          </div>
        </div>
      </div>

Add an input file element to the onchange event,And used in js method singlefileselected, so this method will be called when the user selects and modifies the file.In this method,We will select input file elements and file objects that access filelist,Select the first file files [0], so we can get the file name,File type and other information.

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);
    }
  }

The content of the uploaded file can be read from memory through the file reader object.The reader object provides many events,The onload, onerror and four functions for reading data, readasbinarystring (), readastext (), readasarraybuffer (), readasdataurl (), and the result attribute represent the contents of the file.This attribute is valid only after the read operation is completed.The data format is based on the initial read operation called.

The file reader is not explained in detail here, we will use it in the singlefileselected method,For previewing images,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);
      }

Until now,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,code show as below:

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
    });
  }

In this method,Send the form,Use form data objects to serialize file values,We can manually create instantiations of the formdata data,Suspend the domain value by calling the append () method,Or by retrieving the formdata object of the html form.

The progresshandlingfunction method provides a check whether the uploaded file size can be calculated.Use e.loaded and e.total to calculate what percent of the 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 the basic function of sending data and providing a progress bar has been implemented.Next, you need to implement server-side code processing.Use the upload action method and the uplpader controller.

In the upload method, you can get file information from the httppostedfilebase object,This object contains the basic information of the uploaded file, such as the filename attribute, contenttype attribute, inputstream attribute, etc.This information can be used to verify that the file received by the server is correct.Can also be used to save files.

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);
      }

Can multiple files be uploaded via drag and drop?

In this part,Implement the same uploader and add some new features to the uploader:

Allow selection of multiple files

Drag operation

Now add new functionality to the uplodaer view:

Add multiple attributes to input file elements,To select multiple files at the same time.

Add files that implement drag and drop,As shown in the following code:

<div>drop images here</div>

Add the onchange event in the js method multiplefileselected, similar to the previous singlefileselected,The difference is that all files need to be listed,And allows dragging files.code show as below:

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, fileinfo) {
          if (err!=null) {
            var rowinfo="<div + i +" "
           ><div>"+
                    "<div>" + err + "</div&";+
                   "<div data-name =" filename "
                  >"+ fileinfo.name +"</div>"+
                   "<div data-type =" filetype "
                  >"+ Fileinfo.type +"</div>"+
                   "<div data-size =" filesize "
                  >"+ fileinfo.size () +
                   "</div></div><hr /></div>";
            $("#files"). append (rowinfo);
          }
          else {
            var image="<img src =" "+ fileinfo.filecontent +
            "" +
            fileinfo.name + "" />";
            var rowinfo="<div + i +" "
           ><div>"+
                   "<div data_img =" imagecontainer ">" +
                   image + "</div>" +
                   "<div data-name =" filename "
                  >"+ fileinfo.name +"</div>"+
                   "<div data-type =" filetype "
                  >"+ Fileinfo.type +"</div>"+
                   "<div data-size =" filesize "
                  >"+ fileinfo.size () +
                   "</div></div><hr /></div>";
            $("#files"). append (rowinfo);
          }
        });
      }
    }
  }

In this method,Set the variables of the selection and drag file operation to the global variable selectedfiles, and then scan each file in selectedfiles,The read method will be called from the dataurlreader object to read the file.

The dataurlreader object can call the read method, and take the file object and callback method as the read method parameters.In the above method we created filereader and modified the onload and onerror callback functions of filereader.Call the readasdataurl method to read the file.

The new fileinfo object contains 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);
    }
  };

Select using drag and drop

Since most browsers now perform drag and drop operations,To implement a drag operation,Add dragover and drop events to the drop_zone element.

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);

The dragover event is triggered when the file is dragged to the target position. In the following code,We have modified the dropeffect property of the default browser and datatransfer, the code is as follows:

 function handledragover (evt) {
     evt.preventdefault ();
     evt.datatransfer.effectallowed="copy";
     evt.datatransfer.dropeffect="copy";
   }

Then add a drop event in multiplefileselected to handle the file drop operation.

Most of the features have been improved,Now you need to add an "upload button" and call the uploadmultiplefiles method via the onclick event.

This method is similar to the uploadfile method mentioned above.The difference is to manually validate the formdata object value.

  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<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,All you need to do is accept a list of files,as follows:

public jsonresult uplodmultiple (httppostedfilebase [] uploadedfiles)

Make sure the httppostedfilebase array name is the same as in the append method,Only in this way,mvc can be mapped to the file array.

public jsonresult uplodmultiple (httppostedfilebase [] uploadedfiles)

datastring.append ("uploadedfiles", selectedfiles [i]);

Upload large files

To allow uploading large files,If 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>
   <httpruntime targetframework="." Maxrequestlength="" />

All the functions can be realized here.And can upload files up to 2gb.

  • Previous What-if for Powershell error handling
  • Next JS implements common TAB, pop-up layer effects (TAB tags, zebra crossing, masking layers, etc)