Seneca + Express 构建的微服务中文件上传的问题
发布于 2 年前 作者 Sekaiiiii 1553 次浏览 来自 问答

Seneca & Express 构建微服务中文件上传的问题

问题描述

基于Seneca & Express 技术栈,个人准备弄一个文件存储相关的服务,其中包括了文件上传的功能。通常在只基于Express框架的实现中,常用到multer、multiparty等第三方库用于解析“multipart/form-data”这种类型的数据。然而我将Seneca & Express 组合至一起,在搭配上multer 或者 multiparty来解析“multipart/form-data”的数据时,当请求通过了解析“multipart/form-data”类型的中间件之后,请求无法传递至seneca的函数中进行处理。代码示例如下

file-service.js 启动文件相关微服务入口
// file-service.js 启动文件相关微服务入口
const path = require("path");
const Express = require("express");
const Seneca = require("seneca");
const BodyParser = require('body-parser');
const multiparty = require('multiparty');
const Web = require('seneca-web');
const ExpressAdapter = require('seneca-web-adapter-express');
const uploadAPI = require('./api/upload');
const seneca = Seneca();
const app = Express();

app.use(BodyParser.json());
app.use(BodyParser.urlencoded());
const routes = [
    {
        pin:"role:api,cmd:*",
        prefix:"/file/api",
        map:{uploadFile:{POST:true }}
    }
]
let form = new multiparty.Form({ uploadDir: path.join(__dirname,"uploads") })
app.use("/file/api/uploadFile",(req,res,next)=>{
    form.parse(req, (err, fields, files) => {
        if (err) {
            next(err);
        }
        next();
		//文件正常处理,之后还能被Express的其他中间件处理。
    })
})
const webConfig = {
    routes: routes,
    adapter: ExpressAdapter,
    context: app
}
seneca
    .use(Web, webConfig)
    .use(uploadAPI)
    .ready(() => {
        var server = seneca.export('web/context')();
        server.listen('9001', () => {
            console.log('server started on:9001');
        })
    })
upload.js 向seneca中添加服务
// upload.js 向seneca中添加服务
module.exports = function uploadAPI(options) {
    this.add({ 'role': 'api', 'cmd': 'uploadFile' }, (msg, done) => {
		//请求无法传达到此处
        console.log(msg.request$.query);
        console.log(msg.request$.body);
        console.log(msg.request$.file);
        done(null, { 'success': true, 'msg': '调用成功', data: {} });
    })
}
测试基本情况
  1. 文件能正常上传,经过文件上传相关的中间处理后能继续被Express请求链上的其他中间件继续处理,但是无法被seneca中的服务处理。
  2. 如果不使用文件上传的中间件,请求能直接通过,经过seneca中的服务处理后返回。

备注

  1. 以上代码从实际代码中截取,稍微修改,可能正常运行需要调试。
  2. 个人对于seneca以及express框架并没有太多深入理解过,表述可能不太清楚或者有误的地方希望各位指出。
1 回复

可以通过设置传入web插件的options,将webConfig类似一下设置,主要是将options的parseBody的属性设置为false。

const webConfig = {
    routes: routes,
    adapter: ExpressAdapter,
    context: app,
    options: {
        parseBody: false
    }
}

造成问题的主要原因在于express挂载解析中间件和seneca-web,seneca-web-adpater这几个第三方库冲突了。

回到顶部