application/x-www-form-urlencoded
简介:
Ajax和JQ的默认值就是"application/x-www-form-urlencoded;charset=utf-8",是一种常见的post提交数据方式。
不属于http content-type规范,通常用于浏览器表单提交.
数据组织格式:key1=1&key2=2&key3=3
①使用post时数据会放入请求体的body,使用get方式时
②则会显示在在地址栏(相信大家对这一点深有体会)。
示例
目的:
我想传递以下数据给服务器:
{
key1:1,
key2:2,
key3:3
}
操作:
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
...
xhr.send("key1=1&key2=2&key3=3");
...
结果:
分析:
平时我们使用ajax时,不会手动将一个对象转换成这种格式(“key1=1&key2=2&key3=3”),这是因为插件帮助我们完成了这一步工作。
除此之外,我们也可以通过给form标签设置enctype来达到自动转换格式的效果:
<form action="form_action.asp" enctype="application/x-www-form-urlencoded"></form>
(form标签enctype属性的默认值就是application/x-www-form-urlencoded,这意味着我们从form标签中获得的意见是编码过后的数据,可以直接使用。)
multipart/form-data
简介:
通常上传文件时我们会用到它,它可以将每一个表单项分隔为一个部件,每个部件之间由boundary作为分隔符分隔开,每个部件并为每个部又会分别加上Content-Disposition、Content-Type等信息,由此它既可以传键值对,也可以上传文件。
示例
目的:
我想将下面的数据上传到服务器。
{
size: 806251
name: "favicon.png"
}
操作:
xhr.setRequestHeader("Content-Type", "Content-Type": "multipart/form-data; boundary=----FEN-GE-FU");
...
xhr.send('------FEN-GE-FU\r\nContent-Disposition: form-data; name="size"\r\n\r\n806251\r\n------FEN-GE-FU\r\nContent-Disposition: form-data; name="name"\r\n\r\nfavicon.png\r\n------FEN-GE-FU--');
结果:
分析:
按照约定的格式,以及自定义的boundary分隔符书写好我们的数据,能够被浏览器正确解析出来。
不过通常情况下,我们不需要手动去设置Content-Type为multipart/form-data以及去定义boundary。
因为一般情况下浏览器会根据请求体中的数据来自动的设置相应的请求头,当设置为multipart/form-data时,会自动生成一串随机的boundary用于分割和解析数据。
传文件时:
当我们上传文件时,可以看到,浏览器会为这个部件自动成成Content-Type
上图中,我们上传了一个.PNG文件,浏览器自动这个文件部件设置了Content-Type为application/octet-stream,这种类型会提交一个二进制流。
三、错误使用的情况解析
接收数据方按照Content-Type设置的规则去解析,并使用解析结果。
1、设置了Content-Type=application/x-www-form-urlencoded,但send()方法中上传的是错误格式错误
接收数据的一方依然按照application/x-www-form-urlencoded的规则去解析,有两种结果:
①误打误撞,解析出了键值对,例如:
xhr.send(123);
②解析错误,例如上传了一个formData:
2、设置了Content-Type=multipart/form-data,且写死了boundary的值
例如:
xhr.setRequestHeader("Content-Type", "Content-Type": "multipart/form-data; boundary=----FEN-GE-FU");
事实上,FormData会随机生成分隔符,当我们写死boundary=----FEN-GE-FU时,接收数据方则使用我们手动设置的分隔符----FEN-GE-FU去解析FomData的数据,最终结果当然是无法找到哪怕一个相匹配的分隔符,解析出来的结果自然为空。
3、设置了Content-Type=multipart/form-data,但不设置boundary的值或设置boundary为空
例如:
xhr.setRequestHeader("Content-Type", "Content-Type": "multipart/form-data);
接收数据方将不解析FormData,直接使用。