关于koa-router和koa-multer结合使用(require,module.exports),实现图片上传和表单数据提交的请教
发布于 6 年前 作者 1134506391 4364 次浏览 来自 问答

问题

我想把下面的koa-router改造成require,module.exports形式 1587923364-5b20ecec4625b_articlex.png

前端vue

<script>
export default {
    data() {
        return {
            userAvator: "../../../static/avator.png",
            userName: "",
            userPhone: "",
            userGender: "",
            userType: ""
        };
    },
    methods: {
        getAvator(event) {
            let avator = event.target.files[0];
            if (avator.size > 100000) {
                //不能大于100kb
                return false;
            }
            console.log(avator);
            let windowURL = window.URL;
            this.userAvator = windowURL.createObjectURL(avator);
        },
        submit(event) {
            if (
                this.userName === "" ||
                this.userPhone === "" ||
                this.userGender === "" ||
                this.userType === ""
            ) {
                return false;
            } else {
                event.preventDefault();
    
                let formData = new FormData();
                let data = {
                    userName: this.userName,
                    userPhone: this.userPhone,
                    userGender: this.userGender,
                    userType: this.userType
                };
                data = JSON.stringify(data);
                formData.append("avator", this.userAvator);
                formData.append("data", data);
                let config = {
                    headers: {
                        "Content-Type": "multipart/form-data"
                    }
                };
                axios
                    
                    .post("http://localhost:3000/userInsertInto", formData, config)
                    .then(response => {
                        console.log(response);
                    })
                    .catch(error => {
                        console.log(error);
                    });
            }
        }
    }
};
</script>

改造前

router.post('/userInsertInto', upload.single('file'), async(ctx, next) => {
	//todo
})

改造后

router.post('/userInsertInto', controller.userInsertInto)

改造前,可以正常实现功能

const router = require('koa-router')();
const controller = require('../controller/user');
const multer = require('koa-multer');

var storage = multer.diskStorage({
        //文件保存路径  
        destination: function(req, file, cb) {
            cb(null, 'static/images/')
        },
        //修改文件名称  
        filename: function(req, file, cb) {
            var fileFormat = (file.originalname).split(".");
            cb(null, Date.now() + "." + fileFormat[fileFormat.length - 1]);
        }
    })
    //加载配置  
var upload = multer({ storage: storage });

router.post('/userInsertInto', upload.single('file'), async(ctx, next) => {
    console.log(ctx.req.body)
    let data = JSON.parse(ctx.req.body.data);
    console.log(data);
    ctx.body = {
        msg: "aa"
    }
})

module.exports = router;

1500439720-5b20ecbe0c958_articlex.png

改造后的require,module.exports 模式

require

const router = require('koa-router')();
const controller = require('../controller/user');

router.post('/userInsertInto', controller.userInsertInto)


module.exports = router;

module.exports

const router = require('koa-router')();
const userModel = require('../mysql/mysql');
const multer = require('koa-multer');

var storage = multer.diskStorage({
        //文件保存路径  
        destination: function(req, file, cb) {
            cb(null, 'static/images/')
        },
        //修改文件名称  
        filename: function(req, file, cb) {
            var fileFormat = (file.originalname).split(".");
            cb(null, Date.now() + "." + fileFormat[fileFormat.length - 1]);
        }
    })
    //加载配置  
var upload = multer({ storage: storage });

const userInsertInto = async (ctx) => {
    await upload.single('file');
    console.log(ctx.req.body)
    let data = JSON.parse(ctx.req.body.data);
    ctx.body = {
        msg: "aa"
    }
}

module.exports = {
    userInsertInto: userInsertInto
}

报错

291051166-5b20eca6448e8_articlex.png 3888939042-5b20ed0354e91_articlex.png

10 回复

你改之后multer没解析request啊,所以body才为空,之前是作为中间件传入的,改后你得自己传request/response给multer。await upload.single(‘file’)(ctx.req,ctx.res); 试试。。。

来自✨ Node.js开源项目精选

@vendar 报了另一个错误

  TypeError: Cannot read property 'headers' of undefined
      at hasbody (D:\vue-koa-mysql\koa-server\node_modules\_type-is@1.6.16@type-is\index.js:93:14)
      at typeofrequest (D:\vue-koa-mysql\koa-server\node_modules\_type-is@1.6.16@type-is\index.js:127:8)
      at multerMiddleware (D:\vue-koa-mysql\koa-server\node_modules\_multer@1.3.0@multer\lib\make-middleware.js:18:10)
      at Promise (D:\vue-koa-mysql\koa-server\node_modules\_koa-multer@1.0.2@koa-multer\index.js:38:9)
      at new Promise (<anonymous>)
      at D:\vue-koa-mysql\koa-server\node_modules\_koa-multer@1.0.2@koa-multer\index.js:37:14
      at userInsertInto (D:\vue-koa-mysql\koa-server\controller\user.js:22:32)
      at dispatch (D:\vue-koa-mysql\koa-server\node_modules\_koa-compose@3.2.1@koa-compose\index.js:44:32)
      at next (D:\vue-koa-mysql\koa-server\node_modules\_koa-compose@3.2.1@koa-compose\index.js:45:18)
      at D:\vue-koa-mysql\koa-server\node_modules\_koa-router@7.4.0@koa-router\lib\router.js:346:16


随便手写的,const upload = upload.single(‘file’); await upload(req,res); multer文档参考下。

来自✨ Node.js开源项目精选

如果 multer 不支持async,那你就不能await了,得用callback,自己验证一下

来自✨ Node.js开源项目精选

@vendar 去掉async await之后,还是报错了

undefined
(node:12316) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot read property 'headers' of undefined
(node:12316) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process
with a non-zero exit code.

怎么写的?文档里有说明的 屏幕快照 2018-06-14 下午4.46.18.png

来自✨ Node.js开源项目精选

@vendar 直接router.post后面接multer是可以接收到前端传过来的图片信息和表单数据的

router.post('/userInsertInto', upload.single('file'), async(ctx, next) => {
	//todo
})

router(require)

const router = require('koa-router')();
const controller = require('../controller/user');
router.post('/userInsertInto', controller.userInsertInto)
module.exports = router;

user.js(module.exports)

const router = require('koa-router')();
const userModel = require('../mysql/mysql');
const multer = require('koa-multer');

const userInsertInto = (ctx) => {
    var storage = multer.diskStorage({
            //文件保存路径  
            destination: function(req, file, cb) {
                cb(null, '/static/images/')
            },
            //修改文件名称  
            filename: function(req, file, cb) {
                var fileFormat = (file.originalname).split(".");
                cb(null, Date.now() + "." + fileFormat[fileFormat.length - 1]);
            }
        })
        //加载配置  
    var upload = multer({ storage: storage });
    // upload.single('file')(ctx.req, ctx.res);
    const uploadd = upload.single('file');
    uploadd(ctx.req, ctx.res);
    console.log(ctx.req.file)
        // let data = JSON.parse(ctx.req.body.data);
    ctx.body = {
        msg: "aa"
    }
}

module.exports = {
    userInsertInto: userInsertInto
}

multer的两种用法,一种是post中间件自动调,一种是自己调。

uploadd(ctx.req, ctx.res); 这行需要传入callback,好好看下文档,里面讲的很清楚

来自✨ Node.js开源项目精选

回到顶部