Lösung zum Hochladen von Webordnern

Vor kurzem hatte ich das Bedürfnis, sehr große Dateien hochzuladen. Ich habe die Funktionen zum Schneiden und Hochladen von Qi Niu und Tencent Cloud untersucht und die Implementierung verwandter Funktionen für das Hochladen großer Dateien im Front-End geregelt.

In einigen Unternehmen ist das Hochladen großer Dateien ein relativ wichtiges interaktives Szenario, z. B. die Excel-Tabellen mit einer großen Bibliothek und das Hochladen von Audio- und Videodateien. Wenn die Dateigröße groß ist oder die Netzwerkbedingungen nicht gut sind, ist die Upload-Zeit länger (es werden mehr Pakete übertragen und die Wahrscheinlichkeit eines Paketverlusts und einer erneuten Übertragung ist größer). Der Benutzer kann die Seite nicht aktualisieren und nur geduldig auf den Abschluss der Anforderung warten .

Beginnen wir mit der Methode zum Hochladen von Dateien, organisieren die Idee des Hochladens großer Dateien und geben den entsprechenden Beispielcode an. Da in PHP eine praktische Methode zum Teilen und Spleißen von Dateien integriert ist, verwendet der Servercode PHP zum Beispiel zum Schreiben.

Der Beispielcode für diesen Artikel befindet sich auf github, der Hauptreferenz

Sprechen Sie über das Hochladen großer Dateien

Hochladen großer Dateien

Verschiedene Möglichkeiten zum Hochladen von Dateien

Schauen wir uns zunächst verschiedene Möglichkeiten zum Hochladen von Dateien an.

Normaler Formular-Upload

Die Verwendung von PHP zum Anzeigen regelmäßiger Formular-Uploads ist eine gute Wahl. Erstellen Sie zuerst das Datei-Upload-Formular und geben Sie den Übermittlungstyp des Formulars als enctype = "multipart / form-data" an. Dies gibt an, dass das Formular Binärdaten hochladen muss.

Schreiben Sie dann den Code für den Upload der Datei index.php und verwenden Sie die Methode move_uploaded_file (php Dafa ist gut ...)

Beim Hochladen großer Dateien in das Formular tritt leicht das Problem mit dem Server-Timeout auf. Über xhr kann das Frontend Dateien auch asynchron hochladen, im Allgemeinen nach zwei Ideen.

Upload der Dateikodierung

Die erste Idee ist, die Datei zu codieren und dann auf der Serverseite zu decodieren. Ich habe ein Blog am Frontend geschrieben, um die Bildkomprimierung und das Hochladen zu erreichen. Das Hauptimplementierungsprinzip besteht darin, das Image zur Übertragung in base64 zu konvertieren.

varimgURL = URL.createObjectURL (Datei);

ctx.drawImage (imgURL, 0, 0);

// Holen Sie sich die Kodierung des Bildes und übergeben Sie das Bild als lange Zeichenfolge

vardata = canvas.toDataURL ("image / jpeg", 0.5);

Was auf der Serverseite getan werden muss, ist relativ einfach: Dekodieren Sie zuerst base64 und speichern Sie dann das Bild

$ imgData = $ _REQUEST ['imgData'];

$ base64 = explode (',', $ imgData) [1];

$ img = base64_decode ($ base64);

$ url = './test.jpg';

if (file_put_contents ($ url, $ img)) {

exit (json_encode (array (

url => $ url

)));

}}

Der Nachteil der Base64-Codierung besteht darin, dass das Volumen größer als das Originalbild ist (da Base64 drei Bytes in vier Bytes konvertiert, sodass der codierte Text etwa ein Drittel größer als der Originaltext ist), was sehr groß ist Bei Dateien erhöht sich die Zeit zum Hochladen und Parsen erheblich.

Weitere Informationen zu base64 finden Sie in den Base64-Hinweisen.

Neben der Base64-Codierung können Sie den Dateiinhalt auch direkt im Frontend lesen und im Binärformat hochladen

// Binärdatei lesen

functionreadBinary (Text) {

vardata = newArrayBuffer (text.length);

varui8a = newUint8Array (Daten, 0);

für (vari = 0; i <text.length; i ++) {

ui8a [i] = (text.charCodeAt (i) & 0xff);

}}

console.log (ui8a)

}}

varreader = newFileReader;

Leser. = Funktion {

readBinary (this.result) // Ergebnis lesen oder direkt hochladen

}}

// Den Inhalt der aus der Eingabe gelesenen Datei in das Ergebnisfeld von fileReader einfügen

reader.readAsBinaryString (Datei);

asynchroner Upload von formData

Das FormData-Objekt wird hauptsächlich verwendet, um eine Reihe von Schlüssel / Wert-Paaren zusammenzustellen, die Anforderungen senden, und kann Ajax-Anforderungen flexibler senden. Mit FormData können Sie die Formularübermittlung simulieren.

letfiles = e.target.files // Liefert das Eingabedateiobjekt

letformData = newFormData;

formData.append ('Datei', Datei);

axios.post (url, formData);

Die Serververarbeitungsmethode entspricht im Wesentlichen der direkten Formularanforderung.

iframe keine Aktualisierungsseite

In Browsern auf niedriger Ebene (wie z. B. IE) unterstützt xhr das direkte Hochladen von Formulardaten nicht, sodass nur Formulare zum Hochladen von Dateien verwendet werden können. Die Formularübermittlung selbst führt zu Seitensprüngen, die durch das Zielattribut des Formularformulars verursacht werden. Wessen Werte sind

_self, der Standardwert, öffnet die Antwortseite im selben Fenster

_blank, in neuem Fenster öffnen

_parent, im übergeordneten Fenster öffnen

_top, öffnen Sie im obersten Fenster

Framename, öffnen Sie im Iframe mit dem angegebenen Namen

Wenn Sie Benutzern das Gefühl geben möchten, Dateien asynchron hochzuladen, können Sie iframe nach Framename angeben. Wenn Sie das Zielattribut des Formulars auf einen unsichtbaren Iframe setzen, werden die zurückgegebenen Daten von diesem Iframe akzeptiert, sodass nur dieser Iframe aktualisiert wird. Das zurückgegebene Ergebnis kann auch durch Parsen des Texts in diesem Iframe abgerufen werden.

functionupload {

varnow = + newDate

varid = 'frame' + jetzt

$ ("body"). append (`<iframe style =" display: none; "name =" $ {id} "id =" $ {id} "/>`);

var $ form = $ ("#myForm")

$ form.attr ({

"action": '/index.php',

"Methode": "Post",

"enctype": "multipart / form-data",

"Kodierung": "mehrteilige / Formulardaten",

"Ziel": id

}).einreichen

$ ("#" + id) .on ("load", Funktion {

varcontent = $ (this) .contents.find ("body"). text

Versuchen{

vardata = JSON.parse (Inhalt)

} catch (e) {

console.log (e)

}}

})

}}

Hochladen großer Dateien

Schauen wir uns nun die Timeout-Probleme an, die beim Hochladen großer Dateien mit den oben genannten Upload-Methoden auftreten.

Das Hochladen von Formularen und das Hochladen von Iframes ohne Aktualisierung von Seiten laden tatsächlich Dateien über das Formular-Tag hoch. Auf diese Weise wird die gesamte Anforderung vollständig an den Browser übergeben. Beim Hochladen großer Dateien kann es zu einem Zeitlimit für Anforderungen kommen.

Durch fromData werden tatsächlich eine Reihe von Anforderungsparametern in xhr gekapselt, um Formularanforderungen zu simulieren, wodurch das Problem des Zeitlimits für das Hochladen großer Dateien nicht vermieden werden kann

Durch das Codieren des Uploads können wir den hochgeladenen Inhalt flexibler steuern

Das Hauptproblem beim Hochladen großer Dateien besteht darin, dass in derselben Anforderung eine große Datenmenge hochgeladen werden muss, was zu einem langen Prozess führt. Nach einem Fehler muss der Upload erneut gestartet werden. Stellen Sie sich vor, wenn wir diese Anforderung in mehrere Anforderungen aufteilen, wird die Zeit jeder Anforderung verkürzt. Wenn eine Anforderung fehlschlägt, muss diese Anforderung nur erneut gesendet werden, ohne von vorne zu beginnen, damit große Dateien gelöst werden können Was ist mit dem Upload-Problem?

Aufgrund der oben genannten Probleme scheint es, dass das Hochladen großer Dateien die folgenden Anforderungen erfüllen muss

Support Split Upload Anfrage (d. H. Slice)

Unterstützung des Haltepunkts unterstützen

Unterstützung für die Anzeige des Upload-Fortschritts und die Unterbrechung des Uploads

Als nächstes implementieren wir diese Funktionen nacheinander. Es scheint, dass die Hauptfunktion das Schneiden sein sollte.

Datei schneiden

Referenz: Hochladen großer Dateien

Bei der Upload-Codierungsmethode müssen wir im Front-End nur den binären Inhalt der Datei abrufen, dann den Inhalt aufteilen und schließlich jedes Slice auf den Server hochladen.

In Java ist das Datei-FIle-Objekt eine Unterklasse des Blob-Objekts. Das Blob-Objekt enthält einen wichtigen Methoden-Slice. Durch diese Methode können wir die Binärdatei aufteilen.

Das Folgende ist ein Beispiel für eine geteilte Datei. Für up6 müssen sich Entwickler nicht um die Details der Teilung kümmern. Das Steuerelement hilft dabei, dies zu erreichen. Entwickler müssen sich nur um die Geschäftslogik kümmern.

Wenn das Steuerelement hochgeladen wird, werden relevante Informationen zu den einzelnen Dateiblockdaten hinzugefügt, und der Entwickler kann diese nach dem Empfang der Daten auf der Serverseite selbst verarbeiten.

Nach dem Empfang dieser Slices kann der Server sie zusammenfügen. Im Folgenden finden Sie den Beispielcode für PHP-Spleiß-Slices

Für up6 müssen Entwickler nicht spleißen, up6 hat Beispielcode bereitgestellt und diese Logik implementiert.

Um die Eindeutigkeit sicherzustellen, fügt das Steuerelement Informationen für jeden Dateiblock hinzu, z. B. Blockindex, Block MD5, Datei MD5

Haltepunkt wieder aufnehmen

Up6 verfügt über eine Wiederaufnahmefunktion. Up6 hat die Dateiinformationen auf dem Server und die Dateifortschrittsinformationen auf dem Client gespeichert. Das Steuerelement lädt beim Hochladen automatisch die Dateifortschrittsinformationen, und der Entwickler muss sich nicht um diese Details kümmern. In der Verarbeitungslogik des Dateiblocks muss dieser nur anhand des Dateiblockindex identifiziert werden.

Wenn Sie zu diesem Zeitpunkt die Seite aktualisieren oder den Browser beim Hochladen schließen und dieselbe Datei erneut hochladen, werden die zuvor hochgeladenen Slices nicht erneut hochgeladen.

Die Logik für den Server zum Implementieren der Wiederaufnahme des Haltepunkts ist im Wesentlichen ähnlich, solange die Abfrageschnittstelle des Servers in getUploadSliceRecord aufgerufen wird, um den hochgeladenen Slice-Datensatz abzurufen. Daher wird er hier nicht erweitert.

Darüber hinaus muss bei der Wiederaufnahme des Haltepunkts auch der Fall des Slice-Ablaufs berücksichtigt werden: Wenn die mkfile-Schnittstelle aufgerufen wird, kann der Slice-Inhalt auf der Festplatte gelöscht werden. Wenn der Client die mkfile-Schnittstelle nicht aufgerufen hat, ist es offensichtlich, dass diese Slices auf der Festplatte gespeichert werden Unzuverlässig, unter normalen Umständen hat der Slice-Upload eine Gültigkeitsdauer. Wenn er die Gültigkeitsdauer überschreitet, wird er gelöscht. Aus den oben genannten Gründen muss die Übertragung der Wiederaufnahme des Haltepunkts auch die Implementierungslogik des Slice-Ablaufs synchronisieren.

Effekt fortsetzen

 

Laden Sie den Fortschritt hoch und halten Sie an

Mit der Fortschrittsmethode in xhr.upload können Sie den Fortschritt jedes Slice-Uploads überwachen.

Die Implementierung der Upload-Pause ist ebenfalls relativ einfach. Mit xhr.abort können Sie den Upload der derzeit nicht abgeschlossenen Upload-Slices abbrechen, um den Effekt der Upload-Unterbrechung zu erzielen Hochgeladene Scheibe.

Aus Platzgründen werden die Funktionen für den Upload-Fortschritt und die Pause hier nicht implementiert.

Um den Effekt zu erzielen:

 

Zusammenfassung

Gegenwärtig gibt es in der Community einige ausgereifte Lösungen zum Hochladen großer Dateien, wie z. B. das Qi Niu SDK, das Tencent Cloud SDK usw. Möglicherweise müssen wir eine einfache Bibliothek zum Hochladen großer Dateien nicht manuell implementieren, aber das Prinzip muss noch verstanden werden.

In diesem Artikel werden zunächst verschiedene Möglichkeiten zum Hochladen von Front-End-Dateien beschrieben und anschließend verschiedene Szenarien für das Hochladen großer Dateien sowie verschiedene Funktionen erläutert, die beim Hochladen großer Dateien implementiert werden müssen

Teilen Sie die Datei mithilfe der Slice-Methode des Blob-Objekts in Slices auf

Organisierte die Bedingungen und Parameter, die zum Wiederherstellen von Dateien auf der Serverseite erforderlich sind, und demonstrierte, dass PHP Slices in Dateien wiederherstellt

Setzen Sie den Haltepunkt fort, indem Sie den hochgeladenen Slice-Datensatz speichern

Es gibt immer noch einige Probleme, wie z. B.: Vermeiden Sie einen Speicherüberlauf beim Zusammenführen von Dateien, eine Slice-Invalidierungsstrategie, eine Upload-Fortschrittspause und andere Funktionen

Die Back-End-Codelogik ist größtenteils dieselbe und unterstützt derzeit MySQL, Oracle und SQL. Bevor Sie die Datenbank verwenden können, müssen Sie auf diesen Artikel verweisen, den ich geschrieben habe: http://blog.ncmem.com/wordpress/2019/08/12/java-http%E5%A4%A7%E6%96%87 % E4% BB% B6% E6% 96% AD% E7% 82% B9% E7% BB% AD% E4% BC% A0% E4% B8% 8A% E4% BC% A0 / 
Willkommen, um der Gruppe beizutreten und zu diskutieren: 374992201 

Ich denke du magst

Origin www.cnblogs.com/songsu/p/12719540.html
Empfohlen
Rangfolge