1

多部分表单数据文件上传时间错误正文应该是对象,我也在使用 ajv 插件,但我仍然在使用同样的问题。下面是我的参考代码。

应用程序.js

const fastify = require('fastify')({
    logger: true
});

const Ajv = require('ajv');
const ajv = new Ajv({
    useDefaults: true,
    coerceTypes: true,
    $data: true,
    extendRefs: true
});

ajv.addKeyword("isFileType", {
    compile: (schema, parent, it) => {
        parent.type = "file";
        delete parent.isFileType;
        return () => true;
    },
});

fastify.setSchemaCompiler((schema) => ajv.compile(schema));

路由.js

schema: {
    tags: [{
        name: 'Category'
    }],
    description: 'Post category data',
    consumes: ['multipart/form-data'],
    body: {
        type: 'object',
        isFileType: true,
        properties: {
            name: {
                type: 'string'
            },
            thumb_url: {
                isFileType: true,
                type: 'object'
            },
            img_url: {
                isFileType: true,
                type: 'object'
            },
            status: {
                type: 'number',
                enum: [0, 1],
                default: 1
            }
        },
        required: ['name', 'thumb_url', 'img_url']
    },
    response: {
        201: {
            type: 'object',
            properties: categoryProperties
        }
    }
}

回复

{
    "statusCode": 400,
    "error": "Bad Request",
    "message": "body should be object"
}

我怀疑错误出在我发送数据的方式上,但我无法弄清楚。我已阅读有关此错误的信息,它似乎是在将对象传递给 formData 时生成的,但我正在发送一个字符串,所以我不明白它为什么会发生。提前致谢!

4

1 回答 1

2

我认为您管理多部分的配置是错误的,应该将架构固定为这个工作示例:

const fastify = require('fastify')({ logger: true })

fastify.register(require('fastify-multipart'), {
  addToBody: true
})

const Ajv = require('ajv')
const ajv = new Ajv({
  useDefaults: true,
  coerceTypes: true,
  $data: true,
  extendRefs: true
})

ajv.addKeyword('isFileType', {
  compile: (schema, parent, it) => {
    parent.type = 'file'
    delete parent.isFileType
    return () => true
  }
})

fastify.setSchemaCompiler((schema) => ajv.compile(schema))

fastify.post('/', {
  schema: {
    tags: [{
      name: 'Category'
    }],
    description: 'Post category data',
    consumes: ['multipart/form-data'],
    body: {
      type: 'object',
      properties: {
        name: { type: 'string' },
        thumb_url: { isFileType: true },
        img_url: { isFileType: true },
        status: {
          type: 'number',
          enum: [0, 1],
          default: 1
        }
      },
      required: ['name', 'thumb_url', 'img_url']
    }
  }
}, async (req, reply) => {
  let filepath = path.join(__dirname, `${req.body.thumb_url[0].filename}-${Date.now()}`)
  await fs.writeFile(filepath, (req.body.thumb_url[0].data))

  filepath = path.join(__dirname, `${req.body.img_url[0].filename}-${Date.now()}`)
  await fs.writeFile(filepath, (req.body.img_url[0].data))

  return req.body
})

fastify.listen(3000)

用这个请求调用它:

curl -X POST \
  http://127.0.0.1:3000/ \
  -H 'content-type: multipart/form-data' \
  -F 'thumb_url=@/home/wks/example-file' \
  -F 'img_url=@/home/wks/example-file' \
  -F 'name=fooo'

你会得到:

{
   "thumb_url":[
      {
         "data":{
            "type":"Buffer",
            "data":[
               97,
               115,
               100,
               10
            ]
         },
         "filename":"example-file",
         "encoding":"7bit",
         "mimetype":"application/octet-stream",
         "limit":false
      }
   ],
   "img_url":[
      {
         "data":{
            "type":"Buffer",
            "data":[
               97,
               115,
               100,
               10
            ]
         },
         "filename":"example-file",
         "encoding":"7bit",
         "mimetype":"application/octet-stream",
         "limit":false
      }
   ],
   "name":"foo",
   "status":1
}
于 2020-02-14T07:43:03.617 回答