前提:我司使用了先上传文件到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中 | Boolean | false |
| patchKoa | 将请求体打到 koa 的 ctx.request 中 | Boolean | true |
| jsonLimit | JSON 数据体的大小限制 | String / Integer | 1mb |
| formLimit | 限制表单请求体的大小 | String / Integer | 56kb |
| textLimit | 限制 text body 的大小 | String / Integer | 56kb |
| encoding | 表单的默认编码 | String | utf-8 |
| multipart | 是否支持 multipart-formdate 的表单 | Boolean | false |
| urlencoded | 是否支持 urlencoded 的表单 | Boolean | true |
| 等等 |
2)formidable 的相关配置参数
| 标题 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| multipart | 是否支持多文件上传 | Boolean | true |
| 等等 |
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探究
参考:
如上内容,难免会有错误或者认识偏差,如有问题,希望大家留言指正