阅读 459

上传文件 koa 中间件转发文件至Java

前提:我司使用了先上传文件到koa中间件,后续拿到node中间件返回的key值一起上传到后台Java 目前需求:不要上传文件至koa,中间层只转发到Java后台

一:问题来了

之前使用 koa2 的时候,处理 post 请求使用的是 koa-bodyparser,同时图片上传使用的是 koa-multer,不过 koa-multer 和 koa-route(注意不是 koa-router) 存在不兼容的问题。并且使用koa-bodyparser是拿不到请求的body参数,同时Client端上传的文件里面同样拿不到里面的files参数(无此字段)

但是这两者可以通过 koa-body 代替,并且只是用 koa-body 即可。

koa-body 主要是下面两个依赖:

co-body": "^5.1.1
formidable": "^1.1.1"
复制代码

具体的实现可以在 github 上查看 :github.com/dlau/koa-bo…

二、koa-body 的基本使用

在 koa2 中使用 koa-body,我使用的是全局引入,而不是路由级别的引入,因为考虑到很多地方都有 post 请求或者是文件上传请求,没必要只在路由级别引入

1、安装依赖

yarn add koa-body
## npm i koa-body -S
复制代码

2、mian.ts

省略了 koa 的一些其他代码

import * as bodyParser from 'koa-body';
// 创建Koa 实例
const app = new Koa();

app.use(cors({
    origin: function () {
        return "*"; // 允许来自所有域名请求
    },
    exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
    maxAge: 5,
    credentials: true,
    allowMethods: ['GET', 'POST', 'DELETE'],
    allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}))

app.use(bodyParser({
    formLimit: '100mb',
    jsonLimit:'100mb',
    textLimit:'100mb',
	multipart: true, // 可以上传多个文件 此配置容易忽略
	formidable: {
		maxFileSize:2000 * 1024 * 1024 //上传文件大小
	}

}))
复制代码

3、有用的参数

1)koa-body 的基本参数

标题描述类型默认值
patchNode将请求体打到原生 node.js 的ctx.req中Booleanfalse
patchKoa将请求体打到 koa 的 ctx.request 中Booleantrue
jsonLimitJSON 数据体的大小限制String / Integer1mb
formLimit限制表单请求体的大小String / Integer56kb
textLimit限制 text body 的大小String / Integer56kb
encoding表单的默认编码Stringutf-8
multipart是否支持 multipart-formdate 的表单Booleanfalse
urlencoded是否支持 urlencoded 的表单Booleantrue
等等

2)formidable 的相关配置参数

标题描述类型默认值
multipart是否支持多文件上传Booleantrue
等等

4、获取文件上传后的信息

需要注意的是,如果是获取上传后文件的信息,则需要在 ctx.request.files 中获取。

如果是获取其他的表单字段,则需要在 ctx.request.body 中获取,这是由 koa-body 决定的(默认情况)。

这是上传至koa转发到Java的代码


export const formdataOn = async function (config: PostConfig,ctx:any): Promise<object> {
    const form = new FormData();//此没有安装form-data模块导致undefined
    const file= ctx.request.files?.file as any; 
    // 创建可读流
    const reader = fs.createReadStream(file?.path);
    for (const key in ctx.request.body) {
        if (Object.hasOwnProperty.call(ctx.request.body, key)) {
            const element = ctx.request.body[key];
            form.append(key,element);
        }
    }
    form.append('file',reader) ;
    const res = await axios({
        method: "post",
        url: config.url,
        data: form,
        headers: {
            ...form.getHeaders(),
            'os-type': ctx.header['os-type']
        }
    });
    //此处可以自定义需要返回的字段格式,要不然会报错
    let data = {
        count: res.data,
        respCode: res.respCode,
        respMsg: res.respMsg,
        headers:res.headers
    }
    return data;
}
复制代码
//路由内的代码
const res =  await formdataOn(postConfig,ctx);
ctx.body = JSON.stringify(res); 
复制代码

这样就可以从前端的new FormData() 到node端转发至Java

但是朋友们想过没有 为什么上传文件就需要new FormData() 这种方式,

并且"Content-Type": "multipart/form-data;charset=UTF-8",

想知道的话 点击我的下一篇文章吧 上传文件的FormData()和Content-Type探究

参考:

koa-body的官方github

如上内容,难免会有错误或者认识偏差,如有问题,希望大家留言指正

文章分类
代码人生
文章标签