上傳文件
遇到的問(wèn)題:
最開(kāi)始用koa-multer询一,接口沒(méi)問(wèn)題回調(diào)執(zhí)行了求冷,但是文件沒(méi)有傳上去侠草。
折騰了兩天,發(fā)現(xiàn)注釋掉 app.use(koabody()) 就可以上傳了(這個(gè)問(wèn)題不知道有沒(méi)有人遇到過(guò)置吓,可能是我寫(xiě)的有問(wèn)題无虚,如果知道是什么問(wèn)題請(qǐng)給我留言),但是不用koa-body沒(méi)辦法接收post請(qǐng)求衍锚。
查了一下資料發(fā)現(xiàn)只用 koa-body 就可以完成需求友题, 并不需要其他中間件。
koa-body兩種上傳文件的方法
1戴质、koa-body自帶的方法
這種方法接口都不用寫(xiě)度宦,你沒(méi)看錯(cuò),不用寫(xiě)接口告匠,如果前端不在意是否有返回?cái)?shù)據(jù)的話(huà)
const koabody = require("koa-body");
app.use(koabody({
?"multipart": true, ?? ????//接收f(shuō)orm表單數(shù)據(jù)
?formidable: {
??uploadDir: './', ?? ??????//文件保存路徑
??keepExtensions: true, ????//保持源文件的擴(kuò)展
??onFileBegin: (name, file) => { ??//文件保存之前的預(yù)處理
???file.path = file.name; ?? ??//保存文件名改為源文件的文件名戈抄,否則文件名隨機(jī)
??}
?}
}));
當(dāng)然也可以寫(xiě)個(gè)接口,并不影響文件保存后专,可以同時(shí)進(jìn)行其他操作划鸽。
2、從post接口中讀取文件并保存
由于我在上傳圖片的url里帶了一個(gè)id,要根據(jù)不同的id存到不同的文件夾下裸诽,所以如果用第一個(gè)方法需要在接口回調(diào)里讀文件嫂用,然后復(fù)制到相應(yīng)的文件夾下,再刪除這個(gè)臨時(shí)文件丈冬,非常麻煩嘱函,可以用這個(gè)方法直接存到相應(yīng)的文件夾下
寫(xiě)一個(gè)post接口用來(lái)接收上傳文件的數(shù)據(jù),然后讓我們來(lái)看一下 ctx.request.body image.png]app.use(koabody({"multipart": true}));??//這個(gè)還是要的
里邊的files對(duì)象就是傳上來(lái)的文件埂蕊,是一個(gè)集合往弓,可以多文件同時(shí)上傳,接下來(lái)要把數(shù)據(jù)還原成文件寫(xiě)到磁盤(pán):
const fs = require("fs");
const path = require('path');exports.upload = (ctx) => {
?function witeFile(file){
??const filePath = path.join(tmpdir, file.name);
??const reader = fs.createReadStream(file.path);
??const writer = fs.createWriteStream(filePath);
??reader.pipe(writer);
??filePaths.push(filePath);
?}
?let id = ctx.url.split('id=')[1];
?let tutorialsPath = `${carTutorialsPath}/${id}`;
??//這里是自定義的路徑
?if (!fs.existsSync (tutorialsPath)) {
??fs.mkdirSync (tutorialsPath);
?}
?const tmpdir = path.join(tutorialsPath);
?const filePaths = [];
?const files = ctx.request.body.files || {};
?const params = ctx.request.body.fields
?for (let key in files) {
??const file = files[key];
??if(Object.prototype.toString.call(file) == '[object Array]'){
???for(var j = 0; j < file.length; j++ ){
????witeFile(file[j]);
???}
??}else{
???witeFile(file);
??}
?}
?return true;
}
在post函數(shù)中調(diào)用粒梦,把ctx直接傳進(jìn)來(lái)就可以了
這里是fs官方api:http://nodejs.cn/api/fs.html