koa文件上传

项目地址:https://github.com/zfeig/koa-mvc.git


 //文件上传操作原理
		//var tmpath = path.join(os.tmpdir(), '1.txt');//模拟上传到临时目录的文件
		console.log(tmpath);
		//var ext = ".txt";//上传后生成文件的后缀,一般和上传的文件后缀一致
		//var ph = path.join('public/upload', Date.parse(new Date()).toString() + ext);//生成新的上传文件路径全称
		console.log(ph);
		//var stream = fs.createWriteStream(ph);//创建一个可写流
		//fs.createReadStream(tmpath).pipe(stream);//可读流通过管道写入可写流

使用koa有一段时间了,评价是小巧精悍,只封装了基本的如request对象和response对象到上下文中,其他功能基本上靠第三方中间件来实现。导致的问题是使用起来就不太方便了,比如用koa上传文件,网上资料有限,对于小白而言,文件上传操作就困难多了。


有句话叫办法总比困难多!首先找到了官方的例子点击打开链接  


var parse = require('co-busboy');
app.use(function *(next){
  // ignore non-POSTs
  if ('POST' != this.method) return yield next;

  // multipart upload
  var parts = parse(this);
  var part;

  while (part = yield parts) {
    var stream = fs.createWriteStream(path.join(os.tmpdir(), Math.random().toString()));
    part.pipe(stream);
    console.log('uploading %s -> %s', part.filename, stream.path);
  }

  this.redirect('/');
});

然后按照官方的例子试了下,然并卵。


后来结合php知识分析了下,form表单【注意:enctype="multipart/form-data"】上传文件时,首先会将文件上传到你本机的temp目录,然后执行move_upload_file(tmpfile,newfile);然后node会不会是这样呢?答案是确定的,上传文件大家都是一样的思路。

然后分析了下上面代码:

fs.createWriteStream(path.join(os.tmpdir(), Math.random().toString()));

这里创建一个可写的流对象,即创建一个表单上传后移动到新目录的空文件;而os.tmpDir()刚好是本机临时目录,上面代码表示在临时目录下生成一个随机数空文件;

part.pipe(stream);
上面的代码表示将可读流对象内容写入到可写的流对象,即上面生成的临时文件下的文件;虽然本机跑这段代码报错,但是可以知道part是将request里面的文件对象解析成可读流。


然后koa文件上传原理就清楚了。通过表单上传文件,文件默认会存放到本机临时目录下生成一个临时文件。然后通过流的形式,打开这个临时文件将数据写入到一个新地址的可写文件流里面,前提是要提前创建这个空的可写流文件,即我们上传目标文件。


由于官网上传代码跑不了,为了验证我的思路,先不管表单提交什么文件,假设在临时文件【通过os.tmpDir()获取临时目录】下上传了一个1.txt文件,然后拿到他的地址,新建目标上传地址,通过流的方式写文件,那么这个过程就完成了表单文件上传。


//文件上传操作原理模拟
		//var tmpath = path.join(os.tmpdir(), '1.txt');//模拟上传到临时目录的文件
		console.log(tmpath);
		//var ext = ".txt";//上传后生成文件的后缀,一般和上传的文件后缀一致
		//var ph = path.join('public/upload', Date.parse(new Date()).toString() + ext);//生成新的上传文件路径全称
		console.log(ph);
		//var stream = fs.createWriteStream(ph);//创建一个可写流
		//fs.createReadStream(tmpath).pipe(stream);//可读流通过管道写入可写流
</pre>上面是模拟上传操作,接下来是正式操作了,通过koa-better-body,解析请求,然后通过this.request.body或this.request.files拿到表单/上传信息,完成功能处理<p></p><p>视图 upload.ejs</p><p></p><pre name="code" class="html"><!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="/css/common.css"/>
</head>
<style>
    .main {
        width: 700px;
        margin: 35px auto;
    }
</style>
<body>
<div class="main">
    <form name="form" action="http://localhost:3000/upload" method="post" enctype="multipart/form-data">
        <p>请认真填写以下表单数据,谢谢合作!</p>

        <p><span class="title">账号:</span><input type="text" name="user"/></p>

        <p><span class="title">密码:</span><input type="password" name="pwd"/></p>

        <p><span class="title">性别:</span><input type="radio" name="sex" value="男"/>男  <input type="radio" name="sex" value="女"/>女</p>

        <p><span class="title">籍贯:</span>
            <select name="from" id="from" name="from">
                <option value="北京">北京</option>
                <option value="上海">上海</option>
                <option value="广州">广州</option>
                <option value="深圳">深圳</option>
                <option value="武汉">武汉</option>
            </select>
        </p>
        <p>
            <span class="title">爱好:</span>
            <input type="checkbox" name="hobby" value="游泳"/>游泳  
            <input type="checkbox" name="hobby" value="篮球"/>篮球  
            <input type="checkbox" name="hobby" value="跑步"/>跑步  
        </p>
        <p><input type="file" name="upfile" multiple /></p>
        </p>
        <p><input type="submit" name="btn" value="提交"/></p>
    </form>
</div>
</body>
</html>


路由:

var bodyParse =require('koa-better-body');
 //定义一个上传表单
		router.get('/upload',indexCtrl.upform);

	  //处理上传结果
		router.post('/upload',bodyParse({multipart:true}),indexCtrl.doupload);


控制器:

doupload : function*(){
        // console.log(this.request.body.files);
		//{
		//	fields:{
        //
		//		user :'',
		//		pwd	:'',
		//		sex	:'',
		//		from:'',
		//		hobby[]:'',
		//		files:{'upfile[]':[[object],[object]]}
		//	}
		//}

		var files=this.request.body.files.upfile;
		if(files.length>0){
			for(var item in files){
				var tmpath= files[item]['path'];
				var tmparr =files[item]['name'].split('.');
				var ext ='.'+tmparr[tmparr.length-1];
				var newpath =path.join('public/upload', parseInt(Math.random()*100) + Date.parse(new Date()).toString() + ext);
				console.log(tmpath);
				console.log(newpath);
				var stream = fs.createWriteStream(newpath);//创建一个可写流
				fs.createReadStream(tmpath).pipe(stream);//可读流通过管道写入可写流
			}
		}

        

		//上传成功后的页面跳转
		this.redirect('/');
	}


然后就会发现项目publi/upload下面就会多出几个上传文件了,是不是很简单?


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Node.js Koa 框架中,解析文件上传的 formData 通常使用 koa-body 或 koa-multer 中间件。 1. koa-body 中间件 koa-body 是 Node.js 的一个中间件,用于解析 HTTP 请求体中的数据,支持多种类型的数据格式,包括 JSON、form 和 text 等,还支持 multipart 类型的数据,也就是文件上传时的 formData。 使用 koa-body 中间件解析 formData,需要设置 multipart 参数为 true,如下所示: ```javascript const Koa = require('koa'); const koaBody = require('koa-body'); const app = new Koa(); app.use(koaBody({ multipart: true, })); app.use(async (ctx) => { const file = ctx.request.files.file; console.log(file.name); // 输出上传的文件名 }); app.listen(3000); ``` 2. koa-multer 中间件 koa-multer 是 Node.js 的一个中间件,用于处理文件上传,它支持多种文件上传方式,包括普通上传、多文件上传等。与 koa-body 不同,koa-multer 只处理文件上传,不处理其他类型的请求体数据。 使用 koa-multer 中间件解析 formData,需要先创建一个 multer 实例,然后使用该实例的 single 或 array 方法来处理文件上传,如下所示: ```javascript const Koa = require('koa'); const Router = require('koa-router'); const multer = require('@koa/multer'); const app = new Koa(); const router = new Router(); // 创建 multer 实例 const upload = multer({dest: 'uploads/'}); // 处理单个文件上传 router.post('/upload', upload.single('file'), async (ctx, next) => { console.log(ctx.req.file); // 输出上传的文件信息 }); // 处理多个文件上传 router.post('/uploads', upload.array('files', 10), async (ctx, next) => { console.log(ctx.req.files); // 输出上传的文件信息 }); app.use(router.routes()); app.listen(3000); ``` 在上面的示例中,创建了一个 multer 实例,然后使用该实例的 single 和 array 方法来处理单个文件上传和多个文件上传。在处理上传文件时,需要指定上传文件的字段名,例如 single 方法中的 'file',array 方法中的 'files'。 综上所述,使用 koa-body 或 koa-multer 中间件都可以解析文件上传的 formData。其中,koa-body 可以处理不同类型的请求体数据,而 koa-multer 则更加专注于文件上传。开发者可以根据自己的需求选择合适的中间件。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值