1. EinleitungZuvor wollte das Unternehmen ein globales Upload-Plugin im Verwaltungssystem erstellen, d. h. beim Wechseln zwischen Seiten ist die Upload-Schnittstelle immer noch vorhanden und der Upload wird nicht beeinträchtigt. Vor einem SPA-Framework wie Vue ist dies kein Problem. Der Backend-Chef sagte jedoch, dass wir die Funktionen für das Hochladen mehrerer Teile, das sofortige Hochladen und das Fortsetzen des Hochladens an Haltepunkten implementieren müssen, was überwältigend klingt. Vor langer Zeit habe ich einen Artikel über Webuploader geschrieben, bei dessen Verwendung jedoch viele Probleme festgestellt, und das offizielle Team pflegt dieses Plugin nicht mehr. Nach vielen Tagen der Recherche und Misserfolgen habe ich mich schließlich entschieden, diese Funktion basierend auf dem Plugin Wenn Sie nur grundlegende (nicht angepasste) Upload-Funktionen implementieren möchten, verwenden Sie direkt Der Quellcode dieses Artikels finden Sie hier: https://github.com/shady-xia/Blog/tree/master/vue-simple-uploader 2. Über vue-simple-uploader
Bevor Sie diesen Artikel lesen, wird empfohlen, zuerst die Dokumentation von simple-uploader.js-Dokumentation Installation: Uploader von „vue-simple-uploader“ importieren Vue.use (Uploader) 3. Kapseln Sie die globale Upload-Komponente basierend auf vue-simple-uploader Nach der Einführung von Der Vorlagenteil ist wie folgt. Ich habe die Vorlage und den Stil angepasst, daher ist der HTML-Teil relativ lang. Der CSS-Teil wird vorerst nicht aufgeführt. Sie können ihn entsprechend Ihrer eigenen Benutzeroberfläche ändern. Achten Sie hauptsächlich auf den <Vorlage> <div id="global-uploader"> <!-- Hochladen --> <Uploader ref="Hochlader" :Optionen="Optionen" :autoStart="false" @file-added="beiDateihinzugefügt" @file-success="beiDateierfolg" @file-progress="beiDateifortschritt" @file-error="beiDateifehler" Klasse="Uploader-App"> <Uploader-Unterstützung nicht mehr></Uploader-Unterstützung nicht mehr> <uploader-btn id="global-uploader-btn" :attrs="attrs" ref="uploadBtn">Datei auswählen</uploader-btn> <Uploader-Liste v-show="Panelshow"> <div Klasse = "file-panel" Slot-Scope = "Requisiten": Klasse = "{'collapse': collapse}"> <div Klasse="Dateititel"> <h2>Dateiliste</h2> <div Klasse="operieren"> <el-button @click="fileListShow" type="text" :title="collapse ? 'Erweitern':'Collapse' "> <i class="iconfont" :class="collapse ? 'icon-fullscreen': 'icon-minus-round'"></i> </el-button> <el-button @click="close" type="text" title="Schließen"> <i class="iconfont icon-close"></i> </el-button> </div> </div> <ul Klasse="Dateiliste"> <li v-for="Datei in props.fileList" :key="file.id"> <uploader-file :class="'file_' + file.id" ref="files" :file="file" :list="true"></uploader-file> </li> <div class="no-file" v-if="!props.fileList.length"><i class="nucfont inuc-empty-file"></i> Keine hochzuladenden Dateien</div> </ul> </div> </Uploader-Liste> </uploader> </div> </Vorlage> Der Datenteil in der Komponente: Daten() { zurückkehren { Optionen: Ziel: 'http://xxxxx/xx', // Ziel-Upload-URL chunkSize: '2048000', // Chunk-Größe fileParameterName: 'file', // Dateiparametername beim Hochladen von Dateien, Standarddatei maxChunkRetries: 3, // Maximale Anzahl automatischer fehlgeschlagener Wiederholungsversuche beim Hochladen testChunks: true, // Ob die Serverfragmentierungsüberprüfung aktiviert werden soll // Funktion zur Überprüfung der Serverfragmentierung, Grundlage für sofortiges Hochladen und Wiederaufnehmen von Haltepunkten checkChunkUploadedByResponse: function (chunk, message) { let objMessage = JSON.parse(Nachricht); wenn (objMessage.skipUpload) { gibt true zurück; } return (objMessage.uploaded || []).indexOf(chunk.offset + 1) >= 0 }, Überschriften: { // Verifizierung im Header hinzugefügt, bitte entsprechend der tatsächlichen Geschäftsautorisierung einstellen: „Bearer“ + Ticket.get().access_token }, }, Attribute: { // Akzeptierte Dateitypen wie ['.png', '.jpg', '.jpeg', '.gif', '.bmp'...] Hier kapsele ich accept: ACCEPT_CONFIG.getAll() }, panelShow: false, //Nach Auswahl einer Datei das Upload-Panel anzeigen } }, Globale Referenzen: <globaler Uploader></globaler Uploader> 4. Übersicht über den Datei-Upload-Prozess1. Klicken Sie auf die Schaltfläche, um den Datei-Upload-Vorgang auszulösen: (Wenn Sie nicht die globale Upload-Funktion verwenden, sondern direkt auf Hochladen klicken, ignorieren Sie diesen Schritt.) Da ich ein globales Upload-Plugin erstelle, muss ich zuerst das Upload-Fenster ausblenden. Wenn ich auf eine Upload-Schaltfläche klicke, verwende ich Bus, um ein Klicken Sie auf einer bestimmten Seite auf die Schaltfläche „Hochladen“ und bringen Sie die Parameter in den Hintergrund (sofern vorhanden). Hier verwende ich Bus.$emit('openUploader', { überlegeneID: diese.überlegeneID }) Empfangen Sie das Ereignis in Bus.$on('openUploader', Abfrage => { this.params = Abfrage || {}; wenn (this.$refs.uploadBtn) { // Dadurch wird das Dateiauswahlfenster geöffnet$('#global-uploader-btn').click(); } }); 2. Nach Auswahl der Datei wird das Upload-Fenster angezeigt und die MD5-Berechnung gestartet onFileAdded(Datei) { dies.panelShow = true; // MD5 berechnen, wird weiter unten erwähnt.computeMD5(file); }, Hier gibt es eine Prämisse. Ich habe Nachdem ich die Datei ausgewählt habe, muss ich MD5 berechnen, um die Funktionen der Unterbrechungspunktwiederaufnahme und der sofortigen Übertragung zu implementieren. Daher ist es definitiv nicht möglich, den Upload direkt nach der Auswahl der Datei zu starten. Ich muss warten, bis die MD5-Berechnung abgeschlossen ist, bevor ich den Datei-Upload-Vorgang starten kann. Die spezifische MD5-Berechnungsmethode wird weiter unten erläutert, hier jedoch nur kurz vorgestellt. Während des Upload-Vorgangs wird der Rückruf für den Upload-Fortschritt der Datei kontinuierlich ausgelöst. // Dateifortschritts-Callback onFileProgress(rootFile, file, chunk) { console.log(`Hochladen von ${file.name}, Chunk: ${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`) }, 3. Nachdem die Datei erfolgreich hochgeladen wurde Nachdem die Datei erfolgreich hochgeladen wurde, wird im Rückruf „Upload abgeschlossen“ das vom Server zurückgegebene Feld Hinweis: onFileSuccess(rootFile, Datei, Antwort, Chunk) { let res = JSON.parse(Antwort); // Serverdefinierter Fehler, der vom Uploader nicht abgefangen werden kann, if (!res.result) { this.$message({ Nachricht: res.message, Typ: 'Fehler' }); zurückkehren } // Wenn der Server eine Anfrage zum Zusammenführen zurückgibt if (res.needMerge) { api.mergeSimpleUpload({ tempName: res.tempName, Dateiname: Dateiname, …diese.params, }).dann(Daten => { // Dateizusammenführung erfolgreich Bus.$emit('fileSuccess', data); }).catch(e => {}); // Keine Zusammenführung nötig } else { Bus.$emit('fileSuccess', res); console.log('Hochladen erfolgreich'); } }, beiDateifehler(Stammdatei, Datei, Antwort, Block) { console.log(Fehler) }, 5. Datei-Sharding Wie in der Abbildung gezeigt: Bei großen Dateien werden mehrere Anfragen gesendet. Nachdem Sehen Sie sich die an den Server gesendeten Parameter an. Es ist zu beachten, dass im Falle eines erfolgreichen Datei-Uploads die vom Backend zurückgegebenen Felder verwendet werden, um zu entscheiden, ob eine weitere Dateizusammenführungsanforderung an das Backend gesendet werden soll. 6. MD5-Berechnungsprozess Grundlage für Breakpoint-Resume und Instant-Transfer ist die Berechnung Nach
/** * Berechnen Sie MD5, um einen wiederaufnehmbaren Haltepunkt und eine sofortige Übertragung zu erreichen * @param-Datei */ /** * Berechnen Sie MD5, um einen wiederaufnehmbaren Haltepunkt und eine sofortige Übertragung zu erreichen * @param-Datei */ computeMD5(Datei) { Fügt eine neue Funktion zum Lesen von Dateien hinzu. let Zeit = neues Date().getTime(); let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice; lass currentChunk = 0; Konstante Chunkgröße = 10 * 1024 * 1000; let chunks = Math.ceil(Dateigröße / Chunkgröße); lass spark = neues SparkMD5.ArrayBuffer(); //Setze den Dateistatus auf „MD5 berechnen“ dies.statusSet(Datei.ID, 'md5'); Datei.pause(); ladenWeiter(); fileReader.onload = (e => { spark.append(e.target.result); wenn (aktuellerChunk < chunks) { aktuellerChunk++; ladenWeiter(); // Echtzeitanzeige des MD5-Berechnungsfortschritts this.$nextTick(() => { $(`.myStatus_${file.id}`).text('MD5 überprüfen '+ ((currentChunk/chunks)*100).toFixed(0)+'%') }) } anders { lass md5 = spark.end(); this.computeMD5Success(md5, Datei); console.log(`MD5-Berechnung abgeschlossen: ${file.name} \nMD5: ${md5} \nSegmente: ${chunks} Größe: ${file.size} Zeit: ${new Date().getTime() - time} ms`); } }); fileReader.onerror = Funktion () { this.error(`Fehler beim Lesen der Datei ${file.name}, bitte überprüfen Sie die Datei`) Datei.Abbrechen(); }; Funktion loadNext() { lass start = aktueller Chunk * Chunkgröße; let end = ((Start + Chunkgröße) >= Dateigröße) ? Dateigröße : Start + Chunkgröße; fileReader.readAsArrayBuffer(blobSlice.call(Datei.Datei, Start, Ende)); } }, computeMD5Success(md5, Datei) { // Benutzerdefinierte Parameter direkt in die Optionen der Uploader-Instanz laden Object.assign(this.uploader.opts, { Abfrage: { …diese.params, } }) Datei.eindeutige Kennung = md5; Datei.Lebenslauf(); this.statusRemove(Datei.ID); }, Nachdem wir der uniqueIdentifier-Eigenschaft der Datei einen Wert zugewiesen haben, ist die Kennung in der Anforderung der von uns berechnete MD5-Wert. 7. Sofortiger Upload und Download fortsetzen Nachdem wir Der Server bestimmt anhand
7.1 Für das Frontend Zu Beginn jedes Upload-Vorgangs sendet Für diese Anfrage gibt es mehrere mögliche Ergebnisse: a. Wenn es sich um einen zweiten Upload handelt, wird im Anforderungsergebnis eine entsprechende Markierung angezeigt. Hier ist beispielsweise Abbildung a1: Backend-Rückgabewert bei sofortiger Übertragung Abbildung a2: GIF-Übertragung b. Wenn das Backend Fragmentinformationen zurückgibt, wird der Haltepunkt wieder aufgenommen. Wie in der Abbildung gezeigt, gibt es in den zurückgegebenen Daten ein Abbildung b1: Backend-Rückgabewert bei Wiederaufnahme des Haltepunkts Abbildung b2: Haltepunkt-Fortsetzungs-GIF c. Möglicherweise wird nichts zurückgegeben. Dann handelt es sich um eine brandneue Datei und die vollständige mehrteilige Upload-Logik wird befolgt. 7.2 Front-End-Fragmentierungsprüfung: checkChunkUploadedByResponse Im vorherigen Teil ging es um die Konzepte. Lassen Sie uns nun darüber sprechen, wie das Frontend diese Rückgabewerte verarbeitet. checkChunkUploadedByResponse: Funktion (Chunk, Nachricht) { let objMessage = JSON.parse(Nachricht); wenn (objMessage.skipUpload) { gibt true zurück; } return (objMessage.uploaded || []).indexOf(chunk.offset + 1) >= 0 }, Hinweis: 8. Quellcode und Postscript Insgesamt gibt es mehrere Dateien: Mein Niveau ist begrenzt und ich gebe Ihnen nur eine Idee zu Referenzzwecken. Nachdem ich dieses Plug-In verpackt und die Dateiressourcenbibliothek entwickelt hatte, stellte ich fest, dass ich im Grunde eine einfache Baidu Netdisk realisiert hatte. Es handelt sich um ein Verwaltungssystem mit solch komplizierten Funktionen, das eine Abzocke ist! 8.1 Über das erste Shard-Loss-Problem Zum Problem, dass der Server das erste Fragment nicht empfangen kann, nachdem testChunk aktiviert wurde: Die Get-Anforderung von testChunk bringt standardmäßig das erste Fragment zum Server. Wenn der Server den Status 200 zurückgibt, wird davon ausgegangen, dass der aktuelle Chunk hochgeladen wurde und nicht erneut hochgeladen wird. Aktualisiert am 06.08.2019 1. Optimierte die Berechnung von Datei-MD5 und zeigte den Berechnungsfortschritt von MD5 an Die Methode zur Berechnung 2. Benutzerdefinierter Status hinzugefügt (Ich habe bereits mehrere benutzerdefinierte Zustände gekapselt. Vor kurzem haben einige Freunde gefragt, warum es keine Zustände „MD5 überprüfen“ und „Zusammenführen“ gibt. Ich habe meine Methode geschrieben. Die Methode ist dumm, aber sie kann den Effekt erzielen.) Das Plugin unterstützt ursprünglich nur die folgenden Zustände: Aus geschäftlichen Gründen habe ich mehrere benutzerdefinierte Status hinzugefügt: Da die ersten paar Zustände bereits im Plugin verpackt sind, kann ich den Quellcode nicht ändern und kann nur einen etwas hackigeren Ansatz verwenden: this.statusSet(file.id, 'zusammenführen'); this.statusRemove(Datei.ID); Informationen zur spezifischen Verwendung finden Sie im Quellcode. Gleichzeitig hoffe ich, dass der Plugin-Autor von Simple-Uploader in Zukunft die Konfiguration des benutzerdefinierten Status unterstützt. Dies ist das Ende dieses Artikels über die globale Upload-Plug-in-Funktion basierend auf der Vue-Simple-Uploader-Kapselung für Dateisegment-Upload, sofortigen Upload und Breakpoint-Fortsetzung. Weitere verwandte Inhalte zur Vue-Simple-Uploader-Kapselung finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder durchsuchen Sie die folgenden verwandten Artikel weiter. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
Betriebssystem: Ubuntu 17.04 64-Bit MySQL-Version...
IIS7 Laden Sie das HTTP Rewrite-Modul von der off...
Inhaltsverzeichnis 1: Webpack erstellen 2. Datend...
Tomcat definiert intern mehrere ClassLoader, soda...
Inhaltsverzeichnis Vorwort zx-Bibliothek $`Befehl...
Vorwort Im Entwicklungsprozess ist das Definieren...
Verwenden Sie Vue, um einfach einen Click-Flip-Ef...
Mixins stellen auf flexible Weise verteilte, wied...
<br />Gestalten Sie Ihre Website wissenschaf...
Inhaltsverzeichnis Was ist Rract? Hintergrund Rea...
Ich habe meiner persönlichen Website vor Kurzem e...
1. Zweck Schreiben Sie lokal eine Flask-Anwendung...
Verwandte Artikel: Anfänger lernen einige HTML-Ta...
Die Vorteile dieser Lösung liegen in der Einfachh...
In diesem Artikel finden Sie den spezifischen Cod...