You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

hapi-swagger form payload类型下嵌套对象Joi验证失败

解决hapi-swagger v13.0.2 + hapi v19 文件上传时data被识别为字符串的问题

我刚好遇到过类似的问题,结合你使用的依赖版本(hapi 19.1.1、Joi 17.1.1、hapi-swagger 13.0.2),这个问题主要是新版本hapi-swagger处理form-data类型payload时,对嵌套对象的解析逻辑和旧版本不一样导致的。下面是我亲测有效的解决方法:

1. 调整Joi验证规则,适配form-data的嵌套字段格式

form-data本身并不原生支持嵌套对象结构,新版本hapi-swagger在生成表单时,可能会把嵌套的data对象转换成字符串传递,而不是解析成对象。你可以直接修改Joi schema,针对form-data的扁平字段格式做验证:

// 替换原来的嵌套data对象验证,改用扁平的form字段命名
const uploadSchema = Joi.object({
  'data[name]': Joi.string().required(),
  'data[description]': Joi.string().optional(),
  file: Joi.any().meta({ swaggerType: 'file' }).required()
}).unknown(false);

如果不想修改schema结构,也可以在控制器里手动把字符串格式的data转换成对象(注意要处理解析失败的情况):

const uploadHandler = async (request, h) => {
  let payloadData = request.payload.data;
  
  // 检查data是否为字符串,尝试解析成对象
  if (typeof payloadData === 'string') {
    try {
      payloadData = JSON.parse(payloadData);
    } catch (err) {
      return h.response({ error: 'Invalid data format - must be a valid JSON string' }).code(400);
    }
  }

  // 后续的文件处理和业务逻辑
  return {
    success: true,
    metadata: payloadData,
    uploadedFile: request.payload.file.filename
  };
};

2. 配置正确的路由payload解析选项

确保你的路由payload配置完全支持multipart/form-data的解析,开启parse和multipart选项:

server.route({
  method: 'POST',
  path: '/api/upload',
  options: {
    auth: false,
    payload: {
      output: 'stream', // 保留文件流格式
      parse: true, // 开启自动解析payload
      allow: 'multipart/form-data', // 只允许form-data类型
      multipart: true // 明确启用多部分解析
    },
    tags: ['api'],
    description: 'Upload file with metadata',
    validate: {
      payload: uploadSchema
    },
    handler: uploadHandler
  }
});

3. 优化hapi-swagger插件配置

在注册hapi-swagger时,明确开启multipart支持,确保它能正确识别文件上传字段和form-data结构:

await server.register({
  plugin: require('hapi-swagger'),
  options: {
    info: {
      title: 'File Upload API',
      version: '1.0.0'
    },
    payloadType: 'form',
    multipart: true // 关键:启用multipart表单支持
  }
});

问题根源说明

旧版本hapi-swagger可能会自动把form-data中的data[name]这类字段拼接成嵌套对象,但新版本做了逻辑调整,不再自动处理这种嵌套转换,导致后端接收到的data是字符串而非对象。通过上面的调整,要么适配扁平的字段验证,要么手动转换数据格式,就能解决这个报错。

内容的提问来源于stack exchange,提问作者SAMEER KHANDKE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:27:54