先把“合法”分成三层

  1. 语法:JSON.parse 能解析完整文本,没有围栏、尾逗号和多余说明。
  2. 结构:必填字段存在,类型和值域正确,未知字段按你的契约处理。
  3. 业务:当前用户是否有权操作该订单?同一请求重复送达会不会扣两次款?这些问题不属于 JSON 解析器。

例如 {"order_id":42,"action":"refund"} 是合法 JSON,但如果接口要求 order_id 是字符串,结构校验就应拒绝。即使类型正确,也不能仅凭模型建议就执行退款。

一个可以直接运行的 Node.js 样例

以下代码不依赖第三方包。它演示固定契约的最小手写校验;字段变多时,应使用项目内正式的 Schema 校验器并保留同样的负面测试。

function parseOrderAction(text) {
  const value = JSON.parse(text);
  if (value === null || Array.isArray(value) || typeof value !== 'object') {
    throw new Error('预期是对象');
  }
  const keys = Object.keys(value);
  if (keys.length !== 2 || !keys.includes('order_id') || !keys.includes('action')) {
    throw new Error('字段不符合契约');
  }
  if (typeof value.order_id !== 'string' || !/^[0-9]+$/.test(value.order_id)) {
    throw new Error('order_id 必须是数字字符串');
  }
  if (!['lookup', 'refund'].includes(value.action)) {
    throw new Error('不支持的 action');
  }
  return value;
}

for (const text of [
  '{"order_id":"42","action":"lookup"}',
  '{"order_id":42,"action":"lookup"}',
  '{"order_id":"42","action":"refund","admin":true}'
]) {
  try { console.log('通过:', parseOrderAction(text)); }
  catch (error) { console.log('拒绝:', error.message); }
}

预期是第一条通过,第二条因 order_id 类型被拒,第三条因额外字段被拒。把这三段先贴进JSON 检查器,会发现三条语法都合法;这正是“语法检查”和“业务契约检查”不能混为一谈的证据。

把负面样例加入上线验收

至少测试缺字段、null、数字/字符串混用、额外字段、空字符串、超长输入和多段文本。对模型输出要验证整个响应,而不是在混合文字中找到第一对花括号就当作成功。若接口支持供应商提供的结构化输出约束,也应在应用边界再次校验,因为后续业务仍要处理拒绝、截断和版本变更。

当 action 是 refund 时,上面的函数只完成结构检查。真正执行前,还必须在可信服务端核实当前用户权限、订单状态、金额和幂等键。不能把模型返回的 admin:true 当作授权依据,也不要把退款接口直接暴露给浏览器。

本站的 JSON 检查器不会上传粘贴内容,也不会做 JSON Schema 或权限验证。它适合定位语法问题;生产执行必须在你的服务端完成后两层检查。

规范参考:RFC 8259:JSON、JSON Schema 对象约束。