两条路径的基本差异
表单编码把数据压成「键=值&键=值」的字符串,内容类型为 application/x-www-form-urlencoded,值里的空格按约定写作 +,其余特殊字符做百分号编码;JSON 请求体是一个序列化后的文本,内容类型为 application/json,规范要求使用 UTF-8,不套用加号表示空格的惯例。表达能力上,表单只有扁平键值,数组与嵌套需要特殊约定;JSON 天然支持嵌套、数字与布尔类型。选择依据通常是「数据结构复杂度」与「客户端类型」。
基本信息
| 内容类型 | 表单为 application/x-www-form-urlencoded;JSON 为 application/json |
|---|---|
| 空格处理 | 表单值中常用 + 表示空格;JSON 原样保留空格字符 |
| 结构能力 | 表单为扁平键值;JSON 支持嵌套、数组与类型 |
| 数组约定 | 表单依赖重复键或方括号写法;JSON 直接使用数组 |
| 字符集 | JSON 规范要求 UTF-8;表单取决于页面或请求头声明 |
| 文件上传 | 需使用 multipart 表单编码,JSON 需配合 Base64 等方案 |
典型使用场景
- 传统表单提交:浏览器原生提交、后端框架按表单解析
- 开放接口:结构化数据使用 JSON,便于嵌套与类型表达
- 文件与字段混合:使用 multipart 表单编码承载文件
- 第三方回调:部分平台只支持表单编码,需要适配解析方式
- 调试与排查:确认内容类型与实际格式是否匹配,避免解析出空值
两种请求示例
两种请求示例
# 表单编码:空格按约定写作 +,特殊字符转义
curl -s -X POST https://api.example.com/login \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'user=张三' --data-urlencode 'note=a b' # note 值中的空格会被编码
# JSON 请求体:UTF-8 文本,不套用加号规则
curl -s -X POST https://api.example.com/login \
-H 'Content-Type: application/json' \
-d '{"user":"张三","note":"a b"}'
# 排查:先确认服务端按哪种内容类型解析,再检查字段是否为空对比与选择
| 维度 | 表单编码 | JSON |
|---|---|---|
| 结构 | 扁平键值 | 可嵌套、可数组 |
| 类型 | 全部按字符串处理 | 区分数字、布尔、空值 |
| 空格 | 值中常用 + 表示 | 原样保留,不做特殊处理 |
| 文件上传 | multipart 表单支持 | 需 Base64 或单独上传通道 |
| 浏览器原生提交 | 支持 | 需要脚本发送 |
| 典型适用 | 简单登录、回调、老系统对接 | 结构化业务接口 |
内容类型决定解析路径:服务端一般按请求头选择解析器,若声明为 JSON 而实体是表单串(或反之),得到的是空对象或全字符串字段,而不是报错。联调时先打印原始请求体与请求头,能立刻定位这类问题。
不要把 JSON 当成表单值再传输:把 JSON 文本塞进某个表单字段会造成双重转义,长度膨胀且容易在解析环节丢失结构。需要结构化数据时直接使用 JSON 请求体。
字符集声明要显式:JSON 规范要求 UTF-8,表单编码则依赖页面声明或请求头,两者不一致时中文会出现乱码。接入端的解析实现应固定使用 UTF-8,并在文档中写明约定。