form-data 和 x-www-form-urlencoded
原文:https://blog.csdn.net/u013827143/article/details/86222486
一是数据包格式的区别
二是数据包中非 ANSCII 字符怎么编码,是百分号转码发送还是直接发送
application/x-www-form-urlencoded
1、它是 post 的默认格式,使用 js 中 URLencode 转码方法。包括将 name、value 中的空格替换为加号;将非 ascii 字符做百分号编码;将 input 的 name、value 用‘=’连接,不同的 input 之间用‘&’连接。
2、百分号编码什么意思呢。比如汉字‘丁’吧,他的 utf8 编码在十六进制下是 0xE4B881,占 3 个字节,把它转成字符串‘E4B881’,变成了六个字节,每两个字节前加上百分号前缀,得到字符串“%E4%B8%81”,变成九个 ascii 字符,占九个字节(十六进制下是 0x244534254238253831)。把这九个字节拼接到数据包里,这样就可以传输“非 ascii 字符的 utf8 编码的 十六进制表示的 字符串的 百分号形式”,^_^。
3、同样使用 URLencode 转码,这种 post 格式跟 get 的区别在于,get 把转换、拼接完的字符串用‘?’直接与表单的 action 连接作为 URL 使用,所以请求体里没有数据;而 post 把转换、拼接后的字符串放在了请求体里,不会在浏览器的地址栏显示,因而更安全一些。
multipart/form-data
1、对于一段 utf8 编码的字节,用 application/x-www-form-urlencoded 传输其中的 ascii 字符没有问题,但对于非 ascii 字符传输效率就很低了(汉字‘丁’从三字节变成了九字节),因此在传很长的字节(如文件)时应用 multipart/form-data 格式。smtp 等协议也使用或借鉴了此格式。
2、此格式表面上发送了什么呢。用此格式发送一段一句话和一个文件,
同时请求头里规定了 Content-Type: multipart/form-data; boundary=----WebKitFormBoundarymNhhHqUh0p0gfFa8
可见请求体里不同的 input 之间用一段叫 boundary 的字符串分割,每个 input 都有了自己一个小 header,其后空行接着是数据。
3、此格式实际上发送了什么呢。fiddler 抓包如下
右边明显看到了一段乱码,为什么呢,以汉字‘丁’为例,其 utf8 编码为 0xE4B881,这三个字节会直接拼接到数据包中,即其在实际发送时只占三字节,上图右边是逐字节转为 ascii 字符显示的,因此会显示为三个乱码字符。
4、由上可见,multipart/form-data 将表单中的每个 input 转为了一个由 boundary 分割的小格式,没有转码,直接将 utf8 字节拼接到请求体中,在本地有多少字节实际就发送多少字节,极大提高了效率,适合传输长字节。
评论