koa框架17 koa-better-body
禁用
不处理文件
禁用文件上传
//post数据中间件
server.use(convert(body({
multipart : true
})));
buffer
另一种文件上传形式,也是布尔值
//post数据中间件
server.use(convert(body({
buffer : true
})));
限制上传大小
有三个设置:
- maxFieldsSize 限制一个字段的最大大小 (默认20mb)
- maxFileSize 限制单个文件的最大大小 (默认200mb)
- maxFields 限制字段数量,比如限制最多20个文件上传 (默认1000)
这三个也是配置,单位是字节,1kb=1024字节,1mb=1024kb;
//post数据中间件
server.use(convert(body({
maxFileSize : 10*1024 //限制10kb
})));
这样设置的话,表示所有的文件上传都不能超过10kb,但是按道理来说,应该是针对某一个api接口来设置的。
router.post("/upload", convert(body({
uploadDir: path.resolve(__dirname, "upload"),
maxFileSize : 10 * 1024 * 1024
})));
使用router我们将中间件丢入第二个参数,但是这样的话,我们如果要对这个post路径进行操作的话,又需要写一个post路由
router.post("/upload", convert(body({
uploadDir: path.resolve(__dirname, "upload"),
maxFileSize: 10 * 1024 * 1024
})))
router.post("/upload", async ctx => {
console.log(ctx);
});
这样的话太麻烦了,好在router有一个特性,他支持传入多个函数,他会依次运行
router.post("/upload",fn1,fn2,fn3,fn4..)
router会先运行fn1,在运行fn2,然后这样依次运行后面的函数,所以我们的函数可以这样写
router.post("/upload", convert(body({
uploadDir: path.resolve(__dirname, "upload"),
maxFileSize: 10 * 1024 * 1024
})), async ctx => {
console.log(ctx);
})
既然这样写可以,而且最开始那个函数,我们可以将它改为一个报错函数,这样后面所有的错误都可以在这个函数里面抛出,并且还是针对这个路由的,我们也不用在全局的最上层的报错函数(也是自己写的);写那么多判断了。
错误处理
test.post("/upload", async (ctx, next) => {
try {
await next();
} catch (e) {
console.log(e);
}
}, convert(body({
uploadDir: path.resolve(__dirname, "upload"),
maxFileSize: 1 * 1024 * 1024
})), async ctx => {
console.log(ctx.request.files);
})
此时如果发生错误,我们可以通过try-catch捕获到,然后我们还需要详细判断是不是上传文件的错误
通过e.message
可以输出一条错误的信息字符,然后如果是文件过大的话,这句话往往是:
maxFileSize exceeded, received 1080499 bytes of file data
开头有一句maxFileSize exceeded
;然后我们可以通过es6对字符新增的一个开头判断的方法:startsWith()
router.post("/upload", async (ctx, next) => {
try {
await next();
} catch (e) {
if (e.message.startsWith("maxFileSize exceeded")) {
console.log("文件过大");
} else {
console.log("其他错误");
}
}
}, convert(body({
uploadDir: path.resolve(__dirname, "upload"),
maxFileSize: 1 * 1024 * 1024
})), async ctx => {
console.log(ctx.request.files);
})
然后我们给浏览器返回错误,记得要设置状态码,文件错误推荐407,服务器的错误一般500
router.post("/upload", async (ctx, next) => {
try {
await next();
} catch (e) {
if (e.message.startsWith("maxFileSize exceeded")) {
ctx.state = 407;
ctx.body = "文件过大";
console.log("文件过大");
} else {
ctx.state = 407;
ctx.body = "服务器错误";
console.log("服务器错误");
}
}
}, convert(body({
uploadDir: path.resolve(__dirname, "upload"),
maxFileSize: 1 * 1024 * 1024
})), async ctx => {
console.log(ctx.request.files);
})
这样文件上传就设置好了,如果有能力,我们甚至可以将上传的这个函数封装成统一的方法。
比如:
文件大小,文件上传的路径,都可以作为参数,然后成功的回调,和错误的回调,成功返回ctx,错误返回err对象和err的message。
module.exports = function(config){
return [
fn1,
fn2,
fn3
]
}
//调用
const uoload = require("./uoload");
router.post("/upload",...uoload({
path:"",
size:"",
success:()=>{},
error:()=>{}
}))
差不多就是这样的格式,主要是利用的了es6的一个特性,如果是数组的话,可以在前面加三个点符号,他会自动将数组里面的东西抛出,和之前的多个fn一样
router.post("/upload",fn1,fn2,fn3,fn4..)
然后参数的话,是统一的config对象里面调用。这样变量部分由外部掌控,里面只是处理上传的东西,因为上传可能是多个地方使用,封装后方便统一调用。
自定义调用属性名
koa-better-body这个插件有几个设置可以配置的,比如自定义调用用户上传过来的数据的属性名,之前我们调用用户数据使用的是:
ctx.request.fields
我们可以改为
ctx.request.自定义的名字
这样来获取字段和上传的文件。
//post数据中间件
server.use(convert(body({
fields: "aaa",
files: "bbb"
})));
fields是所有的上传过来的字段,files则仅上传过来的文件数组。
这两个我们都可以自定义属性名来调用,fields就变成了ctx.request.aaa
,files则是ctx.request.bbb
json设置
json可以设置为严格模式:
严格模式
json的key必须要有引号包裹,所有的引号必须为双引号
//post数据中间件
server.use(convert(body({
jsonStrict: true
})));
判断是否为json
//post数据中间件
server.use(convert(body({
detectJSON: function (ctx) {
return /\.json$/i.test(ctx.path);
}
})));
这两个也用的不多,一般默认就行了。
自定义上传的数据类型
如果有需要,我们可以自定义用户上传的数据类型,通过extendTypes进行扩展
//post数据中间件
server.use(convert(body({
extendTypes: {
json: ['application/x-javascript'] // will parse application/x-javascript type body as a JSON string
}
})));
handler也是一个配置,用于解析指定的数据吧,暂时也没多讲,也用不上,暂时不管了。
//post数据中间件
server.use(convert(body({
handler: ()=>{}
})));
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据