koa-formidable模块

最近用koa重写express项目,其中有上传文件的模块,需要用到koa-formidable,在这里做一下记录.
首先是express下formidable模块上传文件

function upfile(req, res) {
    var fs = require('fs');
    var http = require('http');
    var formidable = require('formidable');
    var body = '';
    //req 是一个路由里面的请求
    var form = new formidable.IncomingForm();
    form.parse(req, function (err, fields, files) {
        var file = files.file; // 这里的file是前端命名的
        var filename = file.name;
        var buffer = fs.readFileSync(file.path); // 读取文件,此时就可以上传了
        //...其他的加密,md5,文件大小等等
        //用http模块上传到指定服务器
        var opts = {
            hostname: hostname,
            port: port,
            path: url,
            method: post,
            headers: {
                'Content-Length': buffer.length,
                'Connection': 'Keep-Alive',
                //...其他一些参数
            }
        }
        http.request(opts, function (resp) {
            resp.setEncoding('utf8');
            resp.on('data', function (chunk) {
                body += chunk;   // 这个是上传的服务器返回的结果
            })
            resp.on('end', function () {
                try {
                    var result = JSON.parse(body);
                    return res.send(result); //上传结束客户端返回
                } catch (e) {
                    return res.send(e);
                }
            })
        }).on('error',function(e){
            return res.send(e); //出错后返回
        }).write(buffer)   // http上次
        .end();

    })
}

express里面用法比较直接form.parse(req,callback) 回调函数就可以获取到上传的文件信息,在koa2里面路由下的函数是异步的,也没有回调函数,用的是async/await

    // 这个是一个异步,在路由里面前面是有async的
const upkoafile = async (ctx, next) => {
    var fs = require('fs');
    var formidable = require('koa-formidable'); // 这里用koa下的formidable模块,如果直接套用会出现关于req.on 的报错
    // 直接new formidable.IncomingForm() 也会报错它不能new,或者说下面这句已经帮我们new好了
    var form = formidable.parse(ctx.request);
    /*
    这里的form是一个函数,具体如下
    function (done) {
        var form = opts instanceof formidable.IncomingForm
            ? opts
            : new formidable.IncomingForm(opts)
        form.parse(ctx.req, function (err, fields, files) {
            if (err) return done(err)
            done(null, { fields: fields, files: files })
        })
    }
    看到这里,我想有人应该明白了,koa-formidable只不过在原来的模块基础上加了一点东西,甚至可以不用这个模块
    var formidable = require('formidable');
    var form = new formidable.IncomingForm();
    form.parse(ctx.req,function(){...})
    */
    var p = new Promise((resolve, reject) => {
        form((opt, obj) => {
            var file = obj.files.file;
            var filename = file.name;
            var buffer = fs.readFileSync(file.path); // 读取文件,此时就可以上传了
            //... 到这里就已经回到之前的步骤了,后面的http只需要在合适的地方返回promise就行了
            var opts = {
                //...上面一样
            }
            http.request(opts, function (resp) {
                resp.setEncoding('utf8');
                resp.on('data', function (chunk) {
                    body += chunk;   // 这个是上传的服务器返回的结果
                })
                resp.on('end', function () {
                    try {
                        var result = JSON.parse(body);
                        return resolve(result); //上传结束客户端返回
                    } catch (e) {
                        return reject(e);
                    }
                })
            }).on('error', function (e) {
                return reject(e); //出错后返回
            }).write(buffer)   // http上次
                .end();
        })
    })
    var body = await p; //上面的promise返回
    return ctx.body = body;
}

在koa异步函数中,回调函数中返回会出问题的,也就是return ctx.body这句需要用await接收返回结果,如果在回调函数里面,那koa会直接返回404,并且可能造成其他的错误,比如throw new Error('Can\'t set headers after they are sent.');
在koa2里面对于async/await使用要注意同步返回结果.

你可能感兴趣的:(js工作笔记)