Heim >Web-Frontend >js-Tutorial >Detaillierte Erläuterung der Schritte zum Implementieren des Datei-Uploads und -Downloads in koa2
Dieses Mal werde ich Ihnen eine detaillierte Erklärung der Schritte zum Implementieren des Datei-Uploads in koa2 geben Ein praktischer Fall, werfen wir einen Blick darauf.
VorwortUploads und Downloads kommen in Webanwendungen recht häufig vor, egal ob es sich um Bilder oder andere Dateien handelt. In Koa gibt es viele
Middleware, die uns helfen können, Funktionen schnell zu implementieren.
Datei-UploadWenn wir Dateien im Frontend hochladen, laden wir sie über Formulare hoch, aber die hochgeladenen Dateien können nicht wie normale Parameter auf dem Server über ctx weitergeleitet werden Seite. .request.body erhält. Wir können die Koa-Body-Middleware verwenden, um das Hochladen von Dateien
zu verwalten, wodurch der Anforderungstext in ctx.request abgelegt werden kann.// app.js const koa = require('koa'); const app = new koa(); const koaBody = require('koa-body'); app.use(koaBody({ multipart: true, formidable: { maxFileSize: 200*1024*1024 // 设置上传文件大小最大限制,默认2M } })); app.listen(3001, ()=>{ console.log('koa is listening in 3001'); })Nachdem Sie die Middleware verwendet haben, können Sie den hochgeladenen Dateiinhalt in ctx.request.body.files abrufen. Es muss darauf geachtet werden, maxFileSize festzulegen, andernfalls wird ein Fehler gemeldet, sobald die hochgeladene Datei das Standardlimit überschreitet. Nach Erhalt der Datei müssen wir die Datei im Verzeichnis speichern und eine URL an das Frontend zurückgeben. Der Prozess im Knoten ist Erstellen Sie einen lesbaren Stream-Const-Reader = fs.createReadStream(file.path)
const router = require('koa-router')(); const fs = require('fs'); router.post('/upload', async (ctx){ const file = ctx.request.body.files.file; // 获取上传文件 const reader = fs.createReadStream(file.path); // 创建可读流 const ext = file.name.split('.').pop(); // 获取上传文件扩展名 const upStream = fs.createWriteStream(`upload/${Math.random().toString()}.${ext}`); // 创建可写流 reader.pipe(upStream); // 可读流通过管道写入可写流 return ctx.body = '上传成功'; })Diese Methode eignet sich zum Hochladen von Bildern, Textdateien, komprimierten Dateien usw.
koa-send ist eine statische Dateidienst-Middleware, die zur Implementierung der Datei-Download-Funktion verwendet werden kann.
const router = require('koa-router')(); const send = require('koa-send'); router.post('/download/:name', async (ctx){ const name = ctx.params.name; const path = `upload/${name}`; ctx.attachment(path); await send(ctx, path); })Es gibt zwei Methoden zum Herunterladen im Frontend:
window.open
und Formularübermittlung. Hier wird das einfachere window.open verwendet.<button onclick="handleClick()">立即下载</button> <script> const handleClick = () => { window.open('/download/1.png'); } </script>Die Standardeinstellung von window.open besteht darin, ein neues Fenster zu öffnen, zu blinken und dann zu schließen, was dem Benutzer kein gutes Erlebnis bietet. Sie können den zweiten Parameter window.open('/download/1 hinzufügen .png ', '_self'); , sodass es direkt im aktuellen Fenster heruntergeladen wird. Dadurch wird jedoch die aktuelle Seite durch die URL ersetzt, wodurch Seitenereignisse wie beforeunload ausgelöst werden. Wenn Ihre Seite auf dieses Ereignis lauscht und einige Vorgänge ausführt, hat dies Auswirkungen. Dann können Sie auch ein verstecktes Iframe-Fenster verwenden, um den gleichen Effekt zu erzielen.
<button onclick="handleClick()">立即下载</button> <iframe name="myIframe" style="display:none"></iframe> <script> const handleClick = () => { window.open('/download/1.png', 'myIframe'); } </script>
Batch-Download
Es gibt keinen Unterschied zwischen Batch-Download und Einzel-Download, führen Sie einfach ein paar weitere Downloads durch. Daran ist wirklich nichts auszusetzen. Wäre das Erlebnis nicht besser, wenn Sie so viele Dateien in ein komprimiertes Paket packen und dann nur dieses komprimierte Paket herunterladen würden?
Dateiverpackung
Archiver ist ein Modul, das plattformübergreifende Verpackungsfunktionen in Node.js realisieren kann und ZIP- und TAR-Formate unterstützt.
const router = require('koa-router')(); const send = require('koa-send'); const archiver = require('archiver'); router.post('/downloadAll', async (ctx){ // 将要打包的文件列表 const list = [{name: '1.txt'},{name: '2.txt'}]; const zipName = '1.zip'; const zipStream = fs.createWriteStream(zipName); const zip = archiver('zip'); zip.pipe(zipStream); for (let i = 0; i < list.length; i++) { // 添加单个文件到压缩包 zip.append(fs.createReadStream(list[i].name), { name: list[i].name }) } await zip.finalize(); ctx.attachment(zipName); await send(ctx, zipName); })Wenn Sie den gesamten Ordner direkt packen, ist es nicht erforderlich, jede Datei zu durchlaufen und an das komprimierte Paket anzuhängen.
const zipStream = fs.createWriteStream('1.zip'); const zip = archiver('zip'); zip.pipe(zipStream); // 添加整个文件夹到压缩包 zip.directory('upload/'); zip.finalize();Hinweis: Beim Packen des gesamten Ordners wird die generierte komprimierte Paketdatei generiert kann nicht in diesem Ordner gespeichert werden, da es sonst kontinuierlich gepackt wird.
Probleme mit der chinesischen Kodierung
Wenn der Dateiname Chinesisch enthält, können unerwartete Situationen auftreten. Wenn es also beim Hochladen chinesische Zeichen enthält, kodiere ich den Dateinamen mit encodeURI(), um ihn zu speichern, und entschlüssele ihn dann beim Herunterladen mit decodeURI().
ctx.attachment(decodeURI(path)); await send(ctx, path);ctx.attachment Setzen Sie Content-Disposition auf „attachment“, um den Client anzuweisen, zum Download aufzufordern. Verwenden Sie den entschlüsselten Dateinamen als Namen der herunterzuladenden Datei, sodass beim lokalen Herunterladen weiterhin der chinesische Name angezeigt wird. Im Quellcode von koa-send wird der Dateipfad jedoch mit decodeURIComponent() dekodiert:
// koa-send path = decode(path) function decode (path) { try { return decodeURIComponent(path) } catch (err) { return -1 } }Laden Sie zu diesem Zeitpunkt nach der Dekodierung den Pfad herunter, der Chinesisch enthält Pfad auf unserem Server gespeichert Da es sich um einen verschlüsselten Pfad handelt, kann die entsprechende Datei natürlich nicht gefunden werden. Um dieses Problem zu lösen, lassen Sie es nicht entschlüsseln. Wenn Sie den Koa-Send-Quellcode nicht berühren möchten, können Sie stattdessen eine andere Middleware-Koa-Sendfile verwenden.
const router = require('koa-router')(); const sendfile = require('koa-sendfile'); router.post('/download/:name', async (ctx){ const name = ctx.params.name; const path = `upload/${name}`; ctx.attachment(decodeURI(path)); await sendfile(ctx, path); })Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website! Empfohlene Lektüre:
Vue Axios Request Interception-Implementierungsidee (mit Code)
Detaillierte Erläuterung der Schritte zur Implementierung der Warenkorb- und Adressauswahl in vue2
Detaillierte Erläuterung der Verwendung der Baumsteuerung von vue.js
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Schritte zum Implementieren des Datei-Uploads und -Downloads in koa2. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!