虽然看过几遍 HTTP 权威指南, 可是每次遇到 post 上传文件或者看到 Postman 的 form-data, x-www-form-urlencoded 的时候, 还是有点迷糊. 今天看 everything about curl 的时候, 又谈到了 post 的 payload 内容类型. 索性把它理清楚, 方便自己以后查找.
关于 POST 和 PUT 区别
有 ID, 每次根据 ID 去创建/更新, 就用 PUT, 具有幂等性, 多次提交不影响结果.
没有 ID, 每次都创建, 就用 POST, 不具有幂等性, 多次提交产生多次内容.
网页表单(FORM)提交
网页表单提交时, 若 method 为 POST, 表单的 enctype 属性决定了提交的负载内容(payload)的 MIME(网络多媒体类型)类型. enctype 是 encoding type 的缩写, 表示了内容的编码类型, 相当于告诉接受请求的服务器: 我这边把发送的内容经过了某种编码类型A 编码, 你收到之后也用同样的类型解码一下. 现在(20220102)enctype 可能的值(反映到 Content-Type)只有3种:
-
application/x-www-form-urlencoded 只支持键值对,键值对中间用&分隔开, 比如 name=eric&gender=1&age=50
-
multipart/form-data 如果表单的某个值为文件时(上传文件), 使用这种方式, 否则使用上面编码方式(简单).
-
text/plain HTML5 新加的, 主要用于调试.
除去第三种调试用的, 我们在网页上看到的基本就是上面2种, 如果没有文件上传, 基本是第一种, 因为它最简单, 基本就是把 form 的内容根据键值对使用&连接到一起.
multipart/form-data 要对表单内容的每个项目使用分隔符分开, 它的分隔符比较长, 中间还有空行. 比如我上传一个图片文件(sni.png)和另外一个字段(key1=value1), 它的负载的内容是:
------WebKitFormBoundarycsbFnSl9t4kuAjfv
Content-Disposition: form-data; name="a"; filename="sni.png"
Content-Type: image/png
IHDR................e....sRGB........leXIfMM.*.
<<中间省略 png 里面的1000多行二进制内容>>
...adfas
------WebKitFormBoundarycsbFnSl9t4kuAjfv
Content-Disposition: form-data; name="key1"
value1
------WebKitFormBoundarycsbFnSl9t4kuAjfv--
Ajax 请求表单/代码(微服务)提交表单
这种情况下, Content-type 可以是其它类型: application/xml, application/json
标签: none