JSON Schema 验证器

按 JSON Schema(draft-04 至 2020-12)校验 JSON、YAML 或 JSON Lines,错误定位到数据行和 Schema 关键字,并提示大整数、重复键和全角标点。在浏览器内运行,不上传。

  • 在浏览器中处理
  • 数据不离开你的设备
  • 免费 · 无需注册
自动模式读取 $schema,缺少时使用 Draft 2020-12。菜单可覆盖 $schema。浏览器只保存该菜单和“检查 format”设置,不保存 Schema 与数据。
检查 format 会校验支持的 email、date、uuid 等格式。关闭后将 format 作为注解。无法识别的格式会列在提示中。
输入后等待 300 毫秒自动校验。三个输入框合计超过 1,000,000 个 UTF-16 编码单元时,点击“验证”或按 Ctrl/⌘+Enter。“取消”可停止正在运行的校验。

粘贴 Schema 和数据,结果随输入更新。

粘贴 JSON 或 YAML,也可以打开文件或将文件拖到此框。文件最大 20 MiB。示例菜单会替换两个输入框及被引用的 Schema,然后立即校验。
粘贴 JSON、YAML、JSON Lines,或用单独一行 --- 分隔的多个 YAML 文档。每个文档独立校验。也可以打开或拖入文件,文件最大 20 MiB。
粘贴被引用的 Schema,并为每个 Schema 写入 $id。多个 Schema 以单独一行 --- 分隔。工具不会下载 $ref 指向的网址。
被引用的 Schema($ref 目标)

把 $ref 指向的 Schema 粘贴在这里,每个都要有 "$id"。多个之间用单独一行 --- 分隔。工具不会下载任何网址。

校验错误与提示会显示在这里。

阅读完整使用指南 JSON Schema 在线验证:即时校验 JSON 数据结构与类型约束
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。

示例:订单回调里的 19 位订单号

雪花算法生成的订单号常有 19 位,超出 JavaScript 数字能精确表示的范围(2^53)。下面这份回调数据把订单号写成了数字:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["orderId", "mobile", "amount", "status"],
  "properties": {
    "orderId": { "type": "integer", "maximum": 9007199254740991 },
    "mobile": { "type": "string", "pattern": "^1[3-9][0-9]{9}$" },
    "amount": { "type": "integer", "minimum": 1 },
    "status": { "enum": ["待支付", "已支付", "已退款"] },
    "receiver": { "type": "string", "minLength": 2, "maxLength": 10 }
  }
}
{
  "orderId": 1842390023517843457,
  "mobile": "1381234567",
  "amount": 19.9,
  "status": "已发货",
  "receiver": "张"
}
无法确定(Draft 2020-12):输入涉及校验器无法可靠检查的情况,因此不给出有效或无效的结论。原因见下方。
无法确定,原因:
- 数据中有 JavaScript 无法精确表示的数字:1842390023517843457 被读成 1842390023517843500,而 Schema 会比较数字。
* 数据的 /orderId 中的数字 1842390023517843457(第 2 行)无法在 JavaScript 中精确表示,被读成 1842390023517843500。

数据里写的是 1842390023517843457,浏览器读到的却是 1842390023517843500,而 Schema 要比较这个数字。按改写后的数去判定,结论可能是错的:不加 maximum 时这个字段会“通过”,但通过的是另一个数。所以工具不给出有效或无效的结论,只显示“无法确定”和原因,其他字段的错误也先不列出。Python jsonschema 用任意精度整数,会按原值判断;浏览器里的校验器都做不到。

改法是让订单号在接口里按字符串传输,Schema 用 pattern 约束位数。改完后其余四处问题就显示出来了:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["orderId", "mobile", "amount", "status"],
  "properties": {
    "orderId": { "type": "string", "pattern": "^[0-9]{19}$" },
    "mobile": { "type": "string", "pattern": "^1[3-9][0-9]{9}$" },
    "amount": { "type": "integer", "minimum": 1 },
    "status": { "enum": ["待支付", "已支付", "已退款"] },
    "receiver": { "type": "string", "minLength": 2, "maxLength": 10 }
  }
}
{
  "orderId": "1842390023517843457",
  "mobile": "1381234567",
  "amount": 19.9,
  "status": "已发货",
  "receiver": "张"
}
4 个错误,涉及 4 个位置(Draft 2020-12)。
/mobile (第 3 行第 13 列): 不匹配正则 ^1[3-9][0-9]{9}$  Schema #/properties/mobile/pattern
/amount (第 4 行第 13 列): 必须是 integer,实际是 number  Schema #/properties/amount/type
/status (第 5 行第 13 列): 必须是 "待支付", "已支付", "已退款" 之一  Schema #/properties/status/enum
/receiver (第 6 行第 15 列): 至少 2 个字符,实际 1 个  Schema #/properties/receiver/minLength

amount 以分为单位时应是整数,19.9 被 "type": "integer" 拦下;minLength 按 Unicode 字符计数,“张”是 1 个字符。

示例:输入法打出的全角标点

在中文输入法下手写 JSON,最容易混进全角冒号、全角逗号和中文引号。JSON.parse 只会说“Unexpected token”,本工具会指出是哪个字符、在第几行第几列:

{ "type": "object", "properties": { "city": { "type": "string" } } }
{
  "name": "张三",
  "city": “上海”
}
数据不是有效的 JSON、YAML 或 JSON Lines。
第 3 行第 11 列:"“" 是中文引号,JSON 要用英文双引号(")

点击这条错误,数据框会选中出错的字符。全角冒号 : 和全角空格同样会单独提示。

示例:YAML 配置文件

配置文件常用 YAML。下面的 Schema 和数据都是 YAML,Schema 用 unevaluatedProperties: false 拦下拼错的键:

$schema: https://json-schema.org/draft/2020-12/schema
type: object
required: [appName, port]
properties:
  appName: { type: string }
  port: { type: integer, minimum: 1, maximum: 65535 }
  launchDate: { type: string, format: date }
unevaluatedProperties: false
appName: 订单服务
port: "8080"
launchDate: 2026-10-01
prot: 8081
2 个错误,涉及 2 个位置(Draft 2020-12)。
/port: 必须是 integer,实际是 string  Schema #/properties/port/type
(根): 不允许属性 "prot"(unevaluatedProperties)  Schema #/unevaluatedProperties
* Schema 按 YAML 读取(1 个文档)。日期和 yes / no 保持为字符串(YAML 1.2 core schema)。
* 数据按 YAML 读取(1 个文档)。日期和 yes / no 保持为字符串(YAML 1.2 core schema)。

YAML 按 1.2 core schema 读取,所以 2026-10-01 仍是字符串,能通过 format: date;加了引号的 "8080" 是字符串,不是整数。YAML 的错误只显示路径,不显示行号。

错误怎么归并

Ajv 会把 oneOf / anyOf 每个失败分支的错误全部列出。比如“银行卡或银行账户”两种支付方式,银行卡号写错时,Ajv 会给出 5 条错误,其中 3 条来自根本不相关的账户分支。本工具只在 /payment 显示 1 条错误,并展开 最接近的分支(错误最少的分支,const 判别字段不符的分支排在后面),其他分支折叠起来;分支写成 $ref 时同样有效。if / then 不满足时,直接显示 then 里的错误,并标注“经由 then”。

和其他在线工具的对比

2026-10-02 用同一组输入测试了 cn.bing.com 搜索“json schema 校验”排名第一的在线工具大全(lddgo.net),默认规范为 Draft-07:

输入正确结果lddgo.net本工具
draft-07 中 $ref 旁边写 maxLength忽略 maxLength,通过报 maxLength 错误通过,并提示被忽略
"required": ["constructor"] 校验 {}不通过校验正确不通过
"nullable": true 的字符串字段传 null不通过校验正确不通过,并提示
带 2020-12 $schema 的 Schema正常校验invalid schema : no schema with key or ref按 2020-12 校验
YAML 数据—不支持支持

两者都在浏览器里运行,测试中都没有发出包含数据的请求。lddgo.net 把错误显示为 Ajv 的原始 JSON 对象。

限制

  • 校验器是 Ajv 8.18(ajv-formats 3.0.1、ajv-draft-04 1.0.0)。在官方 JSON Schema Test Suite 的必选用例中,draft-07 有 927/929 项、2020-12 有 1,210/1,301 项给出预期结果,其余(2 项、91 项)显示“无法确定”,没有给出错误结论的用例。Ajv 已知会判错的情况都按“无法确定”处理:$dynamicRef、首个目标没有 $recursiveAnchor 的 $recursiveRef、相对引用加嵌套 $id(Ajv 栈溢出)、unevaluatedItems / unevaluatedProperties 与 contains、缺 then 或 else 的 if、anyOf / oneOf 分支内的 items 组合、改了 $vocabulary 的元 Schema,以及数据中也有的 __proto__ 属性。判定只看 Schema 和数据的结构,所以 Ajv 本来答对的部分用例(例如所有用到 $dynamicRef 的)也在其中。
  • $ref 指向的网址不会被下载。
  • JavaScript 无法精确表示的数字(9007199254740993、1.0000000000000001、1e400 等)会提示并写出行号;Schema 要比较数字时,该文档显示“无法确定”。这类数字出现在 Schema 或 YAML 数据里时一律“无法确定”。0.1、1.0 这类能精确读出的数字照常判定。multipleOf 按十进制数值判断:19.99 是 0.01 的倍数,0.3 是 0.1 的倍数(像 Ajv 那样用浮点数相除会判为不是)。重复的键只保留最后一个值,也会提示。
  • 超过 1 MB 的输入需要点“验证”;超过 20 MB 的文件不读取。
  • pattern 按 ECMA-262 正则(u 标志)执行,\d 只匹配半角数字 0–9。

需要从样例数据生成 Schema,可以用 JSON 转 JSON Schema;只检查 YAML 语法,用 YAML 语法验证器;校验整份接口文档,用 OpenAPI 验证器。

FAQ

支持哪些 JSON Schema 版本?

draft-04、draft-06、draft-07、2019-09 和 2020-12。工具按 $schema 判断版本;没有 $schema 时按 2020-12 校验,与 Python jsonschema、Go santhosh-tekuri/jsonschema 的默认一致。也可以在菜单里指定版本,与 $schema 不一致时会给出提示。

数据会上传吗?

不会。Schema 和数据在浏览器标签页里由 Ajv 校验,工具不会把它们发到任何服务器,也不会下载 $ref 指向的网址:被引用的 Schema 请粘贴到“被引用的 Schema”里。浏览器只保存草案菜单和“检查 format”开关这两项设置。

19 位的订单号为什么校验结果不对?

浏览器用 JSON.parse 读数字,超过 2^53(9007199254740992)的整数会丢失精度,例如 1842390023517843457 会变成 1842390023517843500。Schema 要比较这类数字时,工具显示“无法确定”,并写出原值和读到的值,不按改写后的数下结论。这类 ID 建议在接口里用字符串传输,Schema 写成 "type": "string" 加 pattern。

会检查 format 吗?

“检查 format”打开时(默认)会检查 email、uri、date、date-time、time、duration、hostname、ipv4、ipv6、uuid 等 15 种(ajv-formats 实现)。idn-email、iri 等其他 format 直接通过,并在提示里列出。关闭开关后 format 只作注解,这也是 2020-12 规范和 Python jsonschema 的默认做法。

同一份 Schema 在别的工具里结果不同,以哪个为准?

先看结果下方的提示。常见原因有:草案版本不同;draft-07 里与 $ref 并列的关键字按规范应被忽略;nullable 是 OpenAPI 3.0 的关键字,不属于 JSON Schema;format 是否检查;pattern 按 ECMA-262 正则执行,\d 只匹配半角数字,而 Python 的 re 里 \d 也匹配全角数字。