Maison > interface Web > js tutoriel > le corps du texte

Téléchargement de fichiers Koa2 et téléchargement d'un exemple de code

亚连
Libérer: 2018-05-28 14:29:17
original
1196 Les gens l'ont consulté

Cet article présente principalement l'exemple de code pour le téléchargement et le téléchargement de fichiers dans Koa2. Maintenant, je le partage avec vous et le donne comme référence.

Avant-propos

Le téléchargement et le téléchargement sont assez courants dans les applications Web, qu'il s'agisse d'images ou d'autres fichiers. Dans Koa, il existe de nombreux middlewares qui peuvent nous aider à implémenter rapidement des fonctions.

Téléchargement de fichiers

Lors du téléchargement de fichiers dans le front-end, nous les téléchargeons via des formulaires, mais les fichiers téléchargés ne peuvent pas être transmis via ctx comme les paramètres ordinaires sur le serveur côté .request.body obtient. Nous pouvons utiliser le middleware koa-body pour gérer les téléchargements de fichiers, ce qui peut placer le corps de la requête dans ctx.request.

// 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');
})
Copier après la connexion

Après avoir utilisé le middleware, vous pouvez obtenir le contenu du fichier téléchargé dans ctx.request.body.files. Il faut prêter attention à la définition de maxFileSize, sinon une erreur sera signalée dès que le fichier téléchargé dépasse la limite par défaut.

Après avoir reçu le fichier, nous devons enregistrer le fichier dans le répertoire et renvoyer une URL au front-end. Le processus dans le nœud est

  1. Créer un lecteur const de flux lisible = fs.createReadStream(file.path)

  2. Créer un écrivain const de flux inscriptible = fs.createWriteStream('upload/newpath.txt')

  3. Le flux lisible écrit le flux inscriptible via le tube reader.pipe(writer)

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 = '上传成功';
})
Copier après la connexion

Cette méthode convient au téléchargement d'images, de fichiers texte, de fichiers compressés, etc.

Téléchargement de fichiers

koa-send est un middleware de service de fichiers statique qui peut être utilisé pour implémenter la fonction de téléchargement de fichiers.

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);
})
Copier après la connexion

Il existe deux méthodes de téléchargement sur le front-end : window.open et la soumission de formulaire. Le window.open plus simple est utilisé ici.

<button onclick="handleClick()">立即下载</button>
<script>
 const handleClick = () => {
 window.open(&#39;/download/1.png&#39;);
 }
</script>
Copier après la connexion

Le window.open par défaut consiste ici à ouvrir une nouvelle fenêtre, à flasher puis à fermer, ce qui ne donne pas à l'utilisateur une bonne expérience. Vous pouvez ajouter le deuxième paramètre window.open('/download. /1 .png', '_self'); , il sera donc téléchargé directement dans la fenêtre actuelle. Cependant, cela remplace la page actuelle par l'url, ce qui déclenchera des événements de page tels que beforeunload. Si votre page écoute cet événement et effectue certaines opérations, cela aura un impact. Ensuite, vous pouvez également utiliser une fenêtre iframe masquée pour obtenir le même effet.

<button onclick="handleClick()">立即下载</button>
<iframe name="myIframe" style="display:none"></iframe>
<script>
 const handleClick = () => {
 window.open(&#39;/download/1.png&#39;, &#39;myIframe&#39;);
 }
</script>
Copier après la connexion

Téléchargement par lots

Il n'y a aucune différence entre le téléchargement par lots et le téléchargement unique, effectuez simplement quelques téléchargements supplémentaires. Il n’y a vraiment rien de mal à cela. Si vous regroupez autant de fichiers dans un package compressé et que vous téléchargez ensuite uniquement ce package compressé, l'expérience ne serait-elle pas meilleure ?

File Packaging

archiver est un module qui peut réaliser une fonction d'empaquetage multiplateforme dans Node.js, prenant en charge les formats zip et tar.

const router = require(&#39;koa-router&#39;)();
const send = require(&#39;koa-send&#39;);
const archiver = require(&#39;archiver&#39;);

router.post(&#39;/downloadAll&#39;, async (ctx){
 // 将要打包的文件列表
 const list = [{name: &#39;1.txt&#39;},{name: &#39;2.txt&#39;}];
 const zipName = &#39;1.zip&#39;;
 const zipStream = fs.createWriteStream(zipName);
  const zip = archiver(&#39;zip&#39;);
  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);
})
Copier après la connexion

Si vous emballez directement l'intégralité du dossier, vous n'avez pas besoin de parcourir chaque fichier et de l'ajouter au package compressé

const zipStream = fs.createWriteStream(&#39;1.zip&#39;);
const zip = archiver(&#39;zip&#39;);
zip.pipe(zipStream);
// 添加整个文件夹到压缩包
zip.directory(&#39;upload/&#39;);
zip.finalize();
Copier après la connexion

Remarque : emballez l'intégralité du dossier et générez le fichier de package compressé Il ne peut pas être stocké dans ce dossier, sinon il sera conditionné en continu.

Problèmes d'encodage chinois

Lorsque le nom du fichier contient du chinois, des situations inattendues peuvent se produire. Ainsi, lors du téléchargement, s'il contient du chinois, j'encoderai le nom du fichier avec encodeURI() pour le sauvegarder, puis je le décrypterai avec decodeURI() lors du téléchargement.

ctx.attachment(decodeURI(path));
await send(ctx, path);
Copier après la connexion

ctx.attachment Définissez Content-Disposition sur "attachment" pour demander au client de demander le téléchargement. Utilisez le nom du fichier décodé comme nom du fichier téléchargé à télécharger. De cette façon, lors du téléchargement local, le nom chinois sera toujours affiché.

Cependant, dans le code source de koa-send, le chemin du fichier sera décodé avec decodeURIComponent() :

// koa-send
path = decode(path)

function decode (path) {
 try {
  return decodeURIComponent(path)
 } catch (err) {
  return -1
 }
}
Copier après la connexion

A ce moment, après décodage, téléchargez le chemin contenant le chinois, et sur notre serveur, le chemin codé est stocké, donc naturellement le fichier correspondant est introuvable.

Pour résoudre ce problème, ne le laissez pas décoder. Si vous ne souhaitez pas toucher au code source de koa-send, vous pouvez utiliser un autre fichier middleware koa-send à la place.

const router = require(&#39;koa-router&#39;)();
const sendfile = require(&#39;koa-sendfile&#39;);

router.post(&#39;/download/:name&#39;, async (ctx){
 const name = ctx.params.name;
 const path = `upload/${name}`;
 ctx.attachment(decodeURI(path));
  await sendfile(ctx, path);
})
Copier après la connexion

J'ai compilé ce qui précède pour vous, j'espère que cela vous sera utile à l'avenir.

Articles associés :

Explication détaillée de l'algorithme d'entretien Js

Exemple JS d'un moyen simple d'obtenir et de modifier le contenu du zone de texte de saisie

Explication détaillée du formulaire de vue

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal