Heim  >  Artikel  >  Web-Frontend  >  Implementierung der Datei-Upload-Funktion basierend auf Ajax und HTML5 in MVC

Implementierung der Datei-Upload-Funktion basierend auf Ajax und HTML5 in MVC

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

Dieser Artikel stellt hauptsächlich die relevanten Informationen zur Datei-Upload-Funktion basierend auf Ajax und HTML5 in MVC vor. Freunde, die sie benötigen, können darauf verweisen

Einführung

In der Praxis stoßen wir häufig auf die Funktion zum Hochladen von Dateien und zum Anzeigen des Upload-Fortschritts. In diesem Artikel erfahren Sie, wie Sie die Datei-Upload-Funktion mit Fortschrittsanzeige implementieren, ohne Flash oder ein Plug-In zum Hochladen zu verwenden Dateien.

Grundfunktion: Funktion zum Hochladen von Dateien mit Fortschrittsbalken realisieren

Erweiterte Funktion: Funktion zum Hochladen mehrerer Dateien durch Ziehen und Ablegen von Dateien realisieren

Hintergrund

HTML5 bietet eine Standardmethode für den Zugriff auf lokale Dateien – die Datei-API-Spezifikation kann durch Aufrufen der Datei-API abgerufen werden, und der Client kann auch verwendet werden, um den Typ und die Größe der hochgeladenen Datei zu überprüfen.

Diese Spezifikation umfasst die folgenden Schnittstellen zur Verwendung von Dateien:

Dateischnittstelle: verfügt über „Leseberechtigung“ für die Datei und kann den Dateinamen, den Typ, die Größe usw. abrufen.

FileList-Schnittstelle: Bezieht sich auf eine individuell ausgewählte Dateiliste, die der Benutzeroberfläche zur Benutzerauswahl durch 3525558f8f338d4ea90ebf22e5cde2bc angezeigt werden kann.

XMLHTTPRequest2 ist der unbesungene Held von HTML5. XHR2 ist in etwa das Gleiche wie XMLHttpRequest, aber es fügt auch viele neue Funktionen hinzu, wie folgt:

Binärdaten zum Hochladen/Herunterladen hinzugefügt

2. Während des Upload-Vorgangs wurde das Ereignis „Progress“ (Fortschrittsbalken) hinzugefügt, das mehrere Teile von Informationen enthält:

Gesamt: Ganzzahliger Wert, der zur Angabe der Gesamtzahl der Bytes der übertragenen Daten verwendet wird.
Geladen: Ganzzahliger Wert, der zur Angabe der hochgeladenen Bytes verwendet wird.
lengthComputable: Der Bool-Wert wird verwendet, um zu erkennen, ob die hochgeladene Dateigröße berechenbar ist.

3. Anfrage zur ressourcenübergreifenden Freigabe

Diese neuen Funktionen sorgen dafür, dass Ajax und HTML5 gut zusammenarbeiten und das Hochladen von Dateien sehr einfach wird, ohne dass Flash Player, externe Plug-Ins oder HTML verwendet werden müssen Das ff9c23ada1bcecdd1a0fb5d5a0f18437-Tag kann ausgefüllt werden und der Upload-Fortschrittsbalken kann je nach Serverseite angezeigt werden.

In diesem Artikel wird eine kleine Anwendung geschrieben, die die folgenden Funktionen erreichen kann:

Eine einzelne Datei hochladen und eine Anzeige der Upload-Fortschrittsinformationen bereitstellen.
Erstellen Sie Miniaturansichten von Bildern, wenn Sie Bilder an den Server senden.
Laden Sie mehrere Dateien über die Dateiliste oder den Drag-and-Drop-Vorgang hoch.
Zuerst müssen wir prüfen, ob der Browser XHR2, File API, FormData und Drag-and-Drop-Vorgänge unterstützt.

Code schreiben

Wie lade ich eine einzelne Datei hoch und zeige den Upload-Fortschritt an?

Als Erstes müssen Sie eine einfache Ansicht erstellen:

Definieren Sie ein Formular, das aus Eingabedateielementen und Senden-Schaltflächen besteht.

Verwenden Sie den Bootstrap-Fortschrittsbalken, um den Fortschritt anzuzeigen.

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

Fügen Sie das Eingabedateielement im Onchange-Ereignis hinzu und verwenden Sie es in der JS-Methode SingleFileSelected, sodass diese Methode aufgerufen wird, wenn der Benutzer auswählt und ändert die Datei. Bei dieser Methode wählen wir das Eingabedateielement aus und greifen auf das Dateiobjekt von FileList zu, indem wir die erste Datei files[0] auswählen, damit wir den Dateinamen, den Dateityp und andere Informationen erhalten können.

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

Sie können den Inhalt hochgeladener Dateien aus dem Speicher über das Dateileserobjekt lesen. Das Reader-Objekt bietet viele Ereignisse, onload, onError und vier Funktionen zum Lesen von Daten: readAsBinaryString(), readAsText(), readAsArrayBuffer(), readAsDataURL(), und das Ergebnisattribut repräsentiert den Dateiinhalt. Dieses Attribut ist erst nach Abschluss des Lesevorgangs gültig und das Datenformat wird basierend auf dem aufgerufenen initialisierten Lesevorgang bestimmt.

Ich werde den Dateireader hier nicht im Detail erklären. Wir werden ihn in der SingleFileSelected-Methode verwenden, um eine Vorschau der Bilder anzuzeigen:

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

Bis jetzt können Sie das folgende Bild sehen:

Jetzt müssen Sie die hochgeladene Datei an den Server senden, also das Onclick-Ereignis hinzufügen und es dem JS hinzufügen Aufruf der Methode uploadFile(), der Code lautet wie folgt:

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

Senden Sie bei dieser Methode das Formular und verwenden Sie das Formulardatenobjekt, um den Dateiwert zu serialisieren. Wir können manuell eine Instanz der Formdata-Daten erstellen, indem wir die Methode append() aufrufen, um den Feldwert anzuhängen, oder indem wir das FormData-Objekt des HTML-Formulars abrufen.

Die progressHandlingFunction-Methode prüft, ob die Größe der hochgeladenen Datei berechnet werden kann, und verwendet e.loaded und e.total, um den Prozentsatz der hochgeladenen Daten zu berechnen.

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

Nachdem nun die Grundfunktionen des Sendens von Daten und der Bereitstellung eines Fortschrittsbalkens implementiert wurden, müssen Sie die serverseitige Codeverarbeitung mithilfe der Upload-Aktion implementieren Methode und Uplpader-Controller.

In der Upload-Methode können Sie Dateiinformationen aus dem HttpPostedfileBase-Objekt abrufen. Dieses Objekt enthält grundlegende Informationen der hochgeladenen Datei, wie z. B. das Attribut „Dateiname“, das Attribut „Contenttype“, das Attribut „inputStream“ usw. Diese Informationen können zur Überprüfung verwendet werden Die Serverseite kann auch zum Speichern von Dateien verwendet werden, wenn in den empfangenen Dateien Fehler auftreten.

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

Können die Funktionen zum Hochladen mehrerer Dateien durch Drag-and-Drop-Vorgänge genutzt werden?


In diesem Teil implementieren Sie denselben Uploader und fügen dem Uploader einige neue Funktionen hinzu:

允许选择多个文件
拖拽操作
现在给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加载时的进度条代码

Das obige ist der detaillierte Inhalt vonImplementierung der Datei-Upload-Funktion basierend auf Ajax und HTML5 in MVC. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn