koaファイルアップロード
6597 ワード
アップロードダウンロードは、画像や他のファイルにかかわらず、Webアプリケーションで一般的です.koa 2では、ミドルウェアを使用して機能を迅速に実現できます.
ファイルのアップロード
フロントエンドでファイルをアップロードすると、フォームでアップロードしますが、ファイルをアップロードすると、サーバ側では通常のパラメータのようにctxを通過することはできません.request.body取得
koa-bodyミドルウェアを使用してファイルのアップロードを処理することができ、要求体をctxに接続することができる.requestで.
//app.js
ミドルウェアを使用するとctxを使用することができる.request.body.filesアップロードファイルの内容を取得
maxFileSizeを設定する必要があります.そうしないと、アップロードファイルがデフォルトの制限を超えるとエラーが発生します.
ファイルを受信したら、ディレクトリにファイルを保存し、urlをフロントエンドに返す必要があります.nodeでのプロセスは読み取り可能なストリームconst reader=fsを作成する.createReadStream(file.path) 書き込み可能なストリームconst writer=fsを作成する.createWriteStream('upload/newpath.txt') 読み取り可能なストリームは、パイプを介して書き込み可能なストリームreaderに書き込まれる.pipe(writer)
koa-bodyは、アップロードしたファイルをシステムの一時ファイルに入れ、一時ファイルからupload/ディレクトリの下に読み込みます.実はkoa-bodyはformidableを通じてもいいです.uploadDirプロパティストレージディレクトリの直接設定
そしてctxを通過することができる.request.body.files.fileはアップロードしたファイルに直接入手しました.
ファイルのダウンロード
koa-sendは静的ファイルサービスのミドルウェアであり、ファイルダウンロード機能を実現するために使用することができる.
フロントエンドでダウンロードするには、windowという2つの方法があります.Openとフォームのコミット.ここでは簡単なwindowを使います.open.
ここだOpenのデフォルトは新しいウィンドウを開いて、一瞬で閉じて、ユーザーの体験によくなくて、2番目のパラメータwindowを加えることができます.open('/download/1.png', '_self');,これにより、現在のウィンドウで直接ダウンロードできます.しかし、urlを現在のページに置き換えるとbeforeunloadなどのページイベントがトリガーされ、ページがイベントを傍受して操作を行うと影響します.隠しiframeウィンドウを使用して、同じ効果を達成することもできます.
ダウンロード
ダウンロードと ダウンロードの いはありませんが、 もダウンロードを しているだけです.これでも かに ありません.これだけのファイルを1つの パッケージにパッケージして、この パッケージだけをダウンロードすれば、 すればいいのではないでしょうか.
ファイルパッケージ
アーチバーは...jsでプラットフォーム でパッケージング を できるモジュールでzipとtarフォーマットをサポート
フォルダ を パッケージ すると、 ファイルappendを パッケージに する はありません.
:フォルダ をパッケージ し、 された パッケージファイルをそのフォルダの に することはできません.そうしないと、 えずパッケージ されます.
コードの
ファイル に が まれている 、 の が する があります.だからアップロードする 、 が まれているならファイル をencodeURI()コードして し、ダウンロードする にdecodeURI()を します.
ctx.attachment(decodeURI(path));
await send(ctx, path);
ctx.attachmentはContent-Dispositionを「 ファイル」に し、クライアントにダウンロードのプロンプトを します. されたファイル をダウンロードファイルの としてダウンロードすることで、ローカルにダウンロードされ、 が されます.
ガチョウ、koa-sendのソースコードでは、ファイルパスがdecodeURIComponent() されます.
//koa-send
このとき、 して を むパスをダウンロードしますが、 たちのサーバに されているのは されたパスで、 と するファイルが つかりません.
この を するには、 させないでください.koa-sendソースコードを かしたくない は、 わりに のミドルウェアkoa-sendfileを します.
ファイルのアップロード
フロントエンドでファイルをアップロードすると、フォームでアップロードしますが、ファイルをアップロードすると、サーバ側では通常のパラメータのように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
}
})
)
app.listen(3000,()=>{
console.log("koa is listening on 3000!")
})
ミドルウェアを使用するとctxを使用することができる.request.body.filesアップロードファイルの内容を取得
maxFileSizeを設定する必要があります.そうしないと、アップロードファイルがデフォルトの制限を超えるとエラーが発生します.
ファイルを受信したら、ディレクトリにファイルを保存し、urlをフロントエンドに返す必要があります.nodeでのプロセスは
const router = require('koa-router')()
const fs = require('fs')
router.post('/unload',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-bodyは、アップロードしたファイルをシステムの一時ファイルに入れ、一時ファイルからupload/ディレクトリの下に読み込みます.実はkoa-bodyはformidableを通じてもいいです.uploadDirプロパティストレージディレクトリの直接設定
app.use(koaBody({
multipart: true,
formidable: {
maxFileSize: 200*1024*1024, // , 2M
uploadDir: 'upload/',
onFileBegin: (name, file)=>{ //
const fileFormat = file.name.split('.');
file.name = `${Date.now()}.${fileFormat[fileFormat.length-1]}`
file.path = `upload/${file.name}`;
}
}
}));
そしてctxを通過することができる.request.body.files.fileはアップロードしたファイルに直接入手しました.
const router = require('koa-router')();
const fs = require('fs');
router.post('/upload', async (ctx){
const file = ctx.request.body.files.file; //
return ctx.body = file.path; // upload/xxx.xx
})
ファイルのダウンロード
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という2つの方法があります.Openとフォームのコミット.ここでは簡単なwindowを使います.open.
const handleClick = () => {
window.open('/download/1.png');
}
ここだOpenのデフォルトは新しいウィンドウを開いて、一瞬で閉じて、ユーザーの体験によくなくて、2番目のパラメータwindowを加えることができます.open('/download/1.png', '_self');,これにより、現在のウィンドウで直接ダウンロードできます.しかし、urlを現在のページに置き換えるとbeforeunloadなどのページイベントがトリガーされ、ページがイベントを傍受して操作を行うと影響します.隠しiframeウィンドウを使用して、同じ効果を達成することもできます.
ダウンロード
ダウンロードと ダウンロードの いはありませんが、 もダウンロードを しているだけです.これでも かに ありません.これだけのファイルを1つの パッケージにパッケージして、この パッケージだけをダウンロードすれば、 すればいいのではないでしょうか.
ファイルパッケージ
アーチバーは...jsでプラットフォーム でパッケージング を できるモジュールでzipとtarフォーマットをサポート
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);
})
フォルダ を パッケージ すると、 ファイルappendを パッケージに する はありません.
const zipStream = fs.createWriteStream('1.zip');
const zip = archiver('zip');
zip.pipe(zipStream);
//
zip.directory('upload/');
zip.finalize();
:フォルダ をパッケージ し、 された パッケージファイルをそのフォルダの に することはできません.そうしないと、 えずパッケージ されます.
コードの
ファイル に が まれている 、 の が する があります.だからアップロードする 、 が まれているならファイル をencodeURI()コードして し、ダウンロードする にdecodeURI()を します.
ctx.attachment(decodeURI(path));
await send(ctx, path);
ctx.attachmentはContent-Dispositionを「 ファイル」に し、クライアントにダウンロードのプロンプトを します. されたファイル をダウンロードファイルの としてダウンロードすることで、ローカルにダウンロードされ、 が されます.
ガチョウ、koa-sendのソースコードでは、ファイルパスがdecodeURIComponent() されます.
//koa-send
path = decode(path)
function decode (path) {
try {
return decodeURIComponent(path)
} catch (err) {
return -1
}
}
このとき、 して を むパスをダウンロードしますが、 たちのサーバに されているのは されたパスで、 と するファイルが つかりません.
この を するには、 させないでください.koa-sendソースコードを かしたくない は、 わりに のミドルウェアkoa-sendfileを します.
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);
})
// :
router.post('/uploadfile', async (ctx, next) => {
//
const file = ctx.request.files.file; //
//
const reader = fs.createReadStream(file.path);
let filePath = path.join(__dirname, 'public/upload/') + `/${file.name}`;
//
const upStream = fs.createWriteStream(filePath);
//
reader.pipe(upStream);
return ctx.body = " !";
});
:
router.post('/uploadfiles', async (ctx, next) => {
//
const files = ctx.request.files.file; //
for (let file of files) {
//
const reader = fs.createReadStream(file.path);
//
let filePath = path.join(__dirname, 'public/upload/') + `/${file.name}`;
//
const upStream = fs.createWriteStream(filePath);
//
reader.pipe(upStream);
}
return ctx.body = " !";
});