ホームページ  >  記事  >  ウェブフロントエンド  >  Koa2 でのファイルのアップロードとダウンロードのサンプル コード

Koa2 でのファイルのアップロードとダウンロードのサンプル コード

亚连
亚连オリジナル
2018-05-28 14:29:171176ブラウズ

この記事では主に Koa2 でのファイルのアップロードとダウンロードのサンプル コードを紹介します。

はじめに

画像やその他のファイルであっても、Web アプリケーションではアップロードとダウンロードが比較的一般的です。 Koa には、機能を迅速に実装するのに役立つミドルウェアが多数あります。

ファイルアップロード

フロントエンドでファイルをアップロードする場合、フォームを通じてアップロードしますが、アップロードされたファイルは通常のパラメーターのようにctx.request.bodyを通じてサーバー側で取得することはできません。 koa-body ミドルウェアを使用してファイルのアップロードを処理し、リクエスト本文を 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');
})

ミドルウェアを使用すると、アップロードされたファイルの内容を ctx.request.body.files で取得できます。注意する必要があるのは、maxFileSize の設定です。そうしないと、アップロードされたファイルがデフォルトの制限を超えるとすぐにエラーが報告されます。

ファイルを受信したら、ファイルをディレクトリに保存し、フロントエンドに URL を返す必要があります。ノード内の処理は

  1. 読み取り可能なストリームの作成 const Reader = fs.createReadStream(file.path)

  2. 書き込み可能なストリームの作成 const Writer = fs.createWriteStream('upload/newpath.txt')

  3. 読み取り可能なストリームは、パイプ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 = '上传成功';
})

このメソッドは、画像、テキストファイル、圧縮ファイルなどをアップロードするのに適しています。

ファイルダウンロード

koa-sendは、ファイルダウンロード機能を実装するために使用できる静的ファイルサービスミドルウェアです。

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

フロントエンドでダウンロードするには、window.open とフォーム送信の 2 つの方法があります。ここではより単純な window.open が使用されます。

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

ここでのデフォルトの window.open は、新しいウィンドウを開いてフラッシュしてから閉じることですが、これはユーザーに良いエクスペリエンスを与えません。2 番目のパラメーター window.open('/download/1.png', '_self '); なので、現在のウィンドウに直接ダウンロードされます。ただし、これにより現在のページが URL に置き換えられ、ページがこのイベントをリッスンして何らかの操作を実行する場合、beforeunload などのページ イベントがトリガーされます。次に、非表示の iframe ウィンドウを使用して同じ効果を実現することもできます。

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

バッチダウンロード

バッチダウンロードと単一ダウンロードの間に違いはなく、さらに数回ダウンロードを実行するだけです。これには本当に何の問題もありません。非常に多くのファイルを 1 つの圧縮パッケージにまとめて、この圧縮パッケージのみをダウンロードすれば、エクスペリエンスは向上すると思いませんか?

File Packaging

archiverは、Node.jsでクロスプラットフォームパッケージング機能を実現できるモジュールで、zip形式と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);
})

フォルダー全体を直接パックする場合、各ファイルを走査して圧縮パッケージに追加する必要はありません

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

注: フォルダー全体をパッケージする場合、生成された圧縮パッケージ ファイルをこのフォルダーに保存することはできません。そうでない場合は、パックが続行されます。

中国語エンコードの問題

ファイル名に中国語が含まれている場合、予期しない状況が発生する可能性があります。そこで、アップロード時に漢字が含まれている場合は、encodeURI()でファイル名をエンコードして保存し、ダウンロード時にdecodeURI()で復号化します。

ctx.attachment(decodeURI(path));
await send(ctx, path);

ctx.attachment Content-Disposition を「attachment」に設定して、クライアントにダウンロードを促すよう指示します。デコードされたファイル名をダウンロードするファイルの名前として使用します。これにより、ローカルにダウンロードした場合でも中国語の名前が表示されます。

ただし、koa-sendのソースコードでは、decodeURIComponent():

// koa-send
path = decode(path)

function decode (path) {
 try {
  return decodeURIComponent(path)
 } catch (err) {
  return -1
 }
}

でファイルパスをデコードします。このとき、中国語を含むパスはデコード後にダウンロードされ、エンコードされたパスがサーバーに保存されます。当然、該当するファイルは見つかりません。

この問題を解決するには、デコードさせないでください。 koa-send ソース コードに触れたくない場合は、代わりに別のミドルウェア koa-sendfile を使用できます。

rreee

以上が皆さんのためにまとめたもので、今後皆さんのお役に立てれば幸いです。

関連記事:

Jsインタビューアルゴリズムの詳細説明

入力テキストボックスの内容を取得・変更するJSの簡単なメソッド例

vueフォームの詳細説明

以上がKoa2 でのファイルのアップロードとダウンロードのサンプル コードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。