禁用

不处理文件

禁用文件上传

//post数据中间件
server.use(convert(body({
     multipart : true
})));

buffer

另一种文件上传形式,也是布尔值

//post数据中间件
server.use(convert(body({
     buffer : true
})));

限制上传大小

有三个设置:

  1. maxFieldsSize 限制一个字段的最大大小 (默认20mb)
  2. maxFileSize 限制单个文件的最大大小 (默认200mb)
  3. 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:  ()=>{}
})));
分类: Node 标签: nodekoa文件上传koa-better-body

评论

暂无评论数据

暂无评论数据

目录