koa文件上传的那点事

前言

  • 【音乐博客】在做注册的时候,头像上传到服务器上,使用koa做后台

三个方面

1. 使用formidable库上传文件

  • var formidable = require('formidable')
        var form = new formidable.IncomingForm()
        form.uploadDir = uploadPath
       
        form.parse(ctx.req, function (err, fields, files) {
            console.log('files', files)
            //报错的时候直接抛出错误
            if (err) {
                throw err;
            }
           
            //每当触发事件的时候就产生一个随机数
            // var ran=parseInt(Math.random()*89999+10000);
            //    var extname=path.extname(files.appealFile.name); // m4a  改名用的随机数
            var extname = files.appealFile.name;
            // 要改路径,就改这两个变量的路径就好
            const oldPath = __dirname + "/../" + files.appealFile.path;
            // console.log(oldPath);
            const newPath = __dirname + "/../audio/" + extname;
            // console.log(newPath);
            fs.rename(oldPath, newPath, (err) => {
                if (err) {
                    console.log(err);
                    throw Error('改名失败');
                }
                res.send(newPath).end("success");
            })
        })
  • 结果发现form.parse方法都进不去,更别说后面的保存操作了
  • 尝试过多种方法,最后以失败告终;以前使用node是没问题的,但一到koa这就进不去,也不会报错,不明觉厉

2. 使用koa-body上传文件

  • 最后换种文件上传的方法,使用流的形式上传到本地
  • 安装koa-body
  • npm install koa-body --save

  • 在koa项目中引用koa-body中间件 
  • const koaBody = require('koa-body');
    app.use(koaBody({
        multipart: true,
        formidable: {
            maxFileSize: 200*1024*1024    // 设置上传文件大小最大限制,默认2M
        }
    }));

  • 使用koa-body中间件后,即可通过ctx.request.files获取上传的文件

    提醒:
    新版本的koa-body通过ctx.request.files获取上传的文件
    旧版本的koa-body通过ctx.request.body.files获取上传的文件

  • 获取到文件之后,通过fs将文件保存到服务器的指定目录

  • // 支持多文件上传到本地
    const uploadFile = (fileArr) => {
        var resultArr = []
        fileArr.forEach(element => {
      
          // 防止文件命名一致,文件名后面加上时间的时分
          // const randomNum =  Math.floor((Math.random() * 9 + 1)*1000);
          const randomNum = new Date().getHours()+""+new Date().getMinutes();
      
          // 创建可读流
          const reader = fs.createReadStream(element[1].path);
          let filePath = path.join(__dirname, '../public/node/upload/image/user/') + `${randomNum}_${element[1].name}`;
          // let filePath = path.join(__dirname, '../public/upload/image/user/') + `/${element[1].name}`; 斜杆问题注意一下
          // 创建可写流
          const upStream = fs.createWriteStream(filePath);
          // 可读流通过管道写入可写流
          reader.pipe(upStream);
      
          resultArr.push({
            fileName: element[1].name,
            filePath:  filePath.replace(new RegExp(/(\\)/,"g"),'\\/'),  // 上传到服务器上的真实路径
            fileUrl: `/node/upload/image/user/${randomNum}_${element[1].name}`,  //给前端显示头像
            randomNum: randomNum
          })
        });
      
        return resultArr;
      }

3. 前端上传文件

  • 写法可以做下相对应的修改,这里用的是ts编写
  • html
  • <form  id="sendAppealForm">
    	<a href="javascript:void(0);" class="upload">选择文件 > <span class="unfile">未选择任何文件</span>
    		 <input class="replyFileid"  name="appealFile" id="appealFile" type="file"  multiple="multiple"  />
    	</a>
    </form>
    <el-button
    	type="danger"
    	style="width:100%; margin-bottom:30px;"
    	@click.native.prevent="handleRegiste"
      >{{ $t('registe.registeIn') }}</el-button>
    </el-form>
  •   private handleRegiste() {
         var aaa: any = document.getElementById('sendAppealForm')
         var formData = new FormData(aaa);
      
                    var myDate = new Date();  
                    // formData.append("uploader", JSON.parse(localStorage.getItem("login")).username);    // 上传者
                    formData.append("uploadTime", myDate.toLocaleDateString());       // 上传日期
                  
                  
                    var _this = this;
                   this.uploadFile(formData).then(res => {
                      console.log(res);
                    });
      }
    private uploadFile = (param: any) => {
          console.log(param)
        return new Promise((resolve, reject) => {
          axios
            .post("http://localhost:3000/users/register", param, {
              headers: { "Content-Type": "multipart/form-data" }
            })
            .then(res => {
              resolve(res.data);
            })
            .catch(err => {
              reject(err.data);
            });
        });
      };

最后总结

路过的猿友,要是知道koa使用formidable的用法、和为什么我进不去form.parse方法的原因,方便的话麻烦在评论区告知,谢谢哦!

原文地址

https://juejin.im/post/5ec93c956fb9a047ae451e74#heading-9

参考

NodeJs koa2实现文件上传 :https://www.jianshu.com/p/34d0e1a5ac70

https://juejin.im/post/5ec93c956fb9a047ae451e74

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论