Koa2 ファイルのアップロードとサンプル code_node.js のダウンロード

不言
リリース: 2018-03-31 16:29:19
オリジナル
2510 人が閲覧しました

この記事では主に 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
 }
}
ログイン後にコピー

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

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

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);
})
ログイン後にコピー

関連する推奨事項:

Koa2 フレームワークの CORS を使用してクロスドメイン Ajax リクエストを完了する方法

jQuery+koa2 が Ajax リクエストを実装する方法

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

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

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート