Home  >  Article  >  Web Front-end  >  Implementing file upload function based on Ajax and HTML5 in MVC

Implementing file upload function based on Ajax and HTML5 in MVC

亚连
亚连Original
2018-05-24 16:27:442154browse

This article mainly introduces the relevant information on the file upload function based on Ajax and HTML5 in MVC. Friends in need can refer to the following

Introduction

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

Basic function: realize file upload function with progress bar

Advanced function: realize multiple file upload function by dragging and dropping files

Background

HTML5 provides a standard method of accessing local files - the File API specification. File information can be accessed by calling the File API, and the client can also be used to verify the type and size of the uploaded file. specification.

This specification includes the following interfaces to use files:

File interface: has the "read permission" of the file and can obtain the file name, type, size, etc.

FileList interface: refers to a list of individually selected files, which can be presented to the user interface for user selection through 3525558f8f338d4ea90ebf22e5cde2bc or drag and drop.

XMLHTTPRequest2 is the unsung hero of HTML5. XHR2 is roughly the same as XMLHttpRequest, but it also adds many new features, as follows:

1. Added upload/download binary data

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

Total: Integer value, used to specify the total number of bytes of transmitted data.
Loaded: Integer value, used to specify the uploaded bytes.
lengthComputable: Bool value is used to detect whether the uploaded file size is computable.

3. Cross-resource sharing request

These new features make Ajax and HTML5 work well together, making file uploading very simple, without the need to use Flash Player, external plug-ins or html The ff9c23ada1bcecdd1a0fb5d5a0f18437 tag can be completed, and the upload progress bar can be displayed according to the server side.

This article will write a small application that can achieve the following functions:

Upload a single file and provide upload progress information display.
Create image thumbnails when sending pictures to the server.
Achieve multiple file uploads through 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 to upload a single file and display the upload progress?

The first thing you need to do is to create a simple View:

Define a form consisting of input file elements and submit buttons.

Use Bootstrap progress bar to display progress.

<p id="FormContent">
        <form id="FormUpload"
        enctype="multipart/form-data" method="post">
          <span class="btn btn-success fileinput-button">
            <i class="glyphicon glyphicon-plus"></i>
            <span>Add files...</span>
            <input type="file"
            name="UploadedFile" id="UploadedFile" />
          </span>
          <button class="btn btn-primary start"
          type="button" id="Submit_btn">
            <i class="glyphicon glyphicon-upload"></i>
            <span>Start upload</span>
          </button>
          <button class="btn btn-warning cancel"
          type="button" id="Cancel_btn">
            <i class="glyphicon glyphicon-ban-circle"></i>
            <span>close</span>
          </button>
        </form>
        <p class="progress CustomProgress">
          <p id="FileProgress"
          class="progress-bar" role="progressbar"
      aria-valuenow="" aria-valuemin=""
      aria-valuemax="" style="width %;">
            <span></span>
          </p>
        </p>
        <p class="InfoContainer">
          <p id="Imagecontainer"></p>
          <p id="FileName" class="info">
          </p>
          <p id="FileType" class="info">
          </p>
          <p id="FileSize" class="info">
          </p>
        </p>
      </p>

Add the input file element in the Onchange event and use it in the JS method SingleFileSelected, so this method will be called when the user selects and modifies the file. . In this method, we will select the input file element and access the file object of the FileList, selecting 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&#39;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 uploaded file content 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(), and the result attribute represents the file content. This attribute is only valid after the read operation is completed, and the data format is determined based on the initialized read operation called.

I won’t explain File reader in detail here. We will use it in the SingleFileSelected method to preview 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 picture:

Now you need to send the uploaded file to the server, so add the Onclick event and add it to the JS uploadFile() method Call, the code is as follows:

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 = $(&#39;#FormUpload&#39;)[];
     var dataString = new FormData(form);
    $.ajax({
      url &#39;/Uploader/Upload&#39;, //Server script to process data
      type &#39;POST&#39;,
      xhr function () { // Custom XMLHttpRequest
        var myXhr = $.ajaxSettings.xhr();
        if (myXhr.upload) { // Check if upload property exists
          //myXhr.upload.onprogress = progressHandlingFunction
          myXhr.upload.addEventListener(&#39;progress&#39;, 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 and use the Form data object to serialize the file value. We can manually create an instance of the formdata data. ization, by calling the append() method to append the field value, or by retrieving the FormData object of the HTML form.

The progressHandlingFunction method will check whether the uploaded file Size can be calculated, and use e.loaded and e.total to calculate the percentage of data that has been uploaded.

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

Now that the basic functions of sending data and providing a progress bar have been implemented, we need to implement server-side code processing, using the upload action method and uplpader controller .

In the upload method, you can obtain file information from the HttpPostedfileBase object. This object contains basic information about the uploaded file such as Filename attributes, Contenttype attributes, inputStream attributes, etc. This information can be used to verify the server side. It can also be used to save files if there are any errors in the received 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);
      }

Is it possible to upload multiple files through drag and drop operation?

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

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

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

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

 <p id="drop_zone">Drop images Here</p>

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

 function MultiplefileSelected(evt) {
     evt.stopPropagation();
     evt.preventDefault();
     $(&#39;#drop_zone&#39;).removeClass(&#39;hover&#39;);
     selectedFiles = evt.target.files || evt.dataTransfer.files;
     if (selectedFiles) {
       $(&#39;#Files&#39;).empty();
       for (var i = ; i < selectedFiles.length; i++) {
         DataURLFileReader.read(selectedFiles[i], function (err, fileInfo) {
          if (err != null) {
            var RowInfo = &#39;<p id="File_&#39; + i + &#39;" 
            class="info"><p class="InfoContainer">&#39; +
                    &#39;<p class="Error">&#39; + err + &#39;</p>&#39; +
                   &#39;<p data-name="FileName" 
                   class="info">&#39; + fileInfo.name + &#39;</p>&#39; +
                   &#39;<p data-type="FileType" 
                   class="info">&#39; + fileInfo.type + &#39;</p>&#39; +
                   &#39;<p data-size="FileSize" 
                   class="info">&#39; + fileInfo.size() + 
                   &#39;</p></p><hr/></p>&#39;;
            $(&#39;#Files&#39;).append(RowInfo);
          }
          else {
            var image = &#39;<img src="&#39; + fileInfo.fileContent + 
            &#39;" class="thumb" title="&#39; + 
            fileInfo.name + &#39;" />&#39;;
            var RowInfo = &#39;<p id="File_&#39; + i + &#39;" 
            class="info"><p class="InfoContainer">&#39; +
                   &#39;<p data_img="Imagecontainer">&#39; + 
                   image + &#39;</p>&#39; +
                   &#39;<p data-name="FileName" 
                   class="info">&#39; + fileInfo.name + &#39;</p>&#39; +
                   &#39;<p data-type="FileType" 
                   class="info">&#39; + fileInfo.type + &#39;</p>&#39; +
                   &#39;<p data-size="FileSize" 
                   class="info">&#39; + fileInfo.size() + 
                   &#39;</p></p><hr/></p>&#39;;
            $(&#39;#Files&#39;).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(&#39;image.*&#39;)) {
        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 = &#39;copy&#39;;
     evt.dataTransfer.dropEffect = &#39;copy&#39;;
   }

接着在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 < selectedFiles.length; i++) {
       if (!selectedFiles[i].type.match(&#39;image.*&#39;)) {
         continue;
       }
      }
  // AJAX Request code here
  }

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

  public JsonResult UplodMultiple(HttpPostedFileBase[] uploadedFiles)

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

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

上传大文件

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

<system.webServer>
      <security>
           <requestFiltering>
                <requestLimits maxAllowedContentLength="" />
           </requestFiltering>
      </security>
   </system.webServer>
   <httpRuntime targetFramework="." maxRequestLength=""/>

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

相关文章:

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

jquery与php结合实现AJAX长轮询

js ajax加载时的进度条代码

The above is the detailed content of Implementing file upload function based on Ajax and HTML5 in MVC. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn