Content-Type是指http/https发送信息至服务器时的内容编码类型,Content-Type用于表明发送数据流的类型,服务器根据编码类型使用特定的解析方式,获取数据流中的数据。
在网络请求中,常用的Content-Type有如下:
text/html,如果Content-Type的值是text/html,那么接下来就是浏览器的解析和渲染工作了text/plaintext/csstext/javascriptimage/jpegimage/pngimage/gif
以上几种都是常见的页面资源类型。
application/x-www-form-urlencodedmultipart/form-dataapplication/jsonapplication/xml
以上几种是ajax的请求,表单提交或上传文件的常用的资源类型。
1. application/x-www-form-urlencoded
原生**Form**表单默认的提交方式,支持GET/POST等方法,所有数据被格式化成键值对key1=value1&key2=value2 形式的字符串(特殊字符需要转义成utf-8编码,如/会变成%2F)。
首先来看下form表单中POST默认提交方式的数据,代码如下:
<form action="http://www.example.com" method="POST"><p>username: <input type="text" name="fname" /></p><p>age: <input type="text" name="age" /></p><input type="submit" value="提交" /></form>
请求信息如下:

GET请求的话,格式化的字符串将直接拼接在url后发送到服务端;POST请求的话,格式化的字符串将放在请求体的Form Data中发送,但是在chrome的network面板下,form形式的请求体是被解析的,展示成formData的形式。
再来看下使用jQuery的ajax方法提交的数据,代码如下:
var obj = {"name": 'CntChen',"info": 'Front-End',};$('.btn').click(function() {$.ajax({url: 'www.example.com',type: 'POST',dataType: 'json',data: obj,success: function(d) {}})});
请求信息如下:

可以看出,使用jQuery的post请求默认的Content-Type为application/x-www-form-urlencoded。
控制台中访问不到
formData的数据,在控制台看到的是FormData原型,存储的数据没有以对象属性的方式体现,可以理解为类的私有字段,外界访问不到,但是可以通过formData.get("name")的方式获取到对应的表单数据。
2. multipart/form-data
使用表单上传文件时,必须指定表单的enctype属性值为multipart/form-data。 请求体被分割成多部分,每部分使用--boundary分割。
代码如下:
<form action="http://www.example.com" method="POST" enctype="multipart/form-data"><input type="file" id="imageInput" name="file" /></form>
请求信息如下:

3. application/json
在http请求中,Content-Type的默认值都为application/x-www-form-urlencoded, 这种编码格式的特点是:name/value键值对,每组之间使用&连接,而name与value之间是使用=连接,比如key=SHEN&name=111&password=123456。键值对一般的情况下是没有什么问题的,是很简单的json形式,比如如下:
{"name": 111,"password": 123456}
它会解析成name=111&password=123456这样的形式。但是在一些复杂的情况下,比如需要传一个复杂的json对象,也就是对象嵌套数组的情况下,比如如下代码:
{obj: [{"name": 111,"password": 123456}]}
如果将这样复杂的对象,以**application/x-www-form-urlencoded**形式传递的话,会被解析成**obj[0]['name']=111&obj[0].['password']=123456**这样的形式。然后再转成json形式:
{"obj": [{"name": 111,"password": 123456}]}
对于一些复杂的数据对象,比如对象里面再嵌套数组的话,建议使用application/json传递比较好,后台那边也会要求使用application/json。因为后台那边不使用application/json,而使用默认的application/x-www-form-urlencoded传递的话,还要额外的多一步将参数再解析成json对象,如果是更复杂的json对象,那么后台的工作量将更大,所以直接json对象传递的话,对于后台来说更简单。
通过json的形式将数据发送给服务器。json的形式的优点是它可以传递结构复杂的数据形式,比如对象里面嵌套数组这样的形式等。
代码如下:
$('.btn').click(function() {$.ajax({url: 'http://www.example.com',type: 'POST',dataType: 'json',contentType: 'application/json',data: JSON.stringify({a: [{b:1, a:1}]}),success: function(res) {}})});
但是如上代码,在浏览器运行后,发现跨域了,我们看如下截图所示:


3.1 理解 ajax 跨域设置 Content-Type:application/json
在使用**ajax**跨域请求时,如果设置**Header**的**Content-Type**为**application/json**,它会发两次请求。第一次先发**Method**为**OPTIONS**的请求到服务器,这个请求会询问服务器支持那些请求方法(比如**GET**,**POST**)等。如果这个请求支持跨域的话,就会发送第二个请求,否则的话在控制台会报错,第二个请求不会请求。
OPTIONS请求的返回图如下:

图中箭头指向的Allow就是服务器返回的支持的方法。不仅如此,如果想要用**application/json**发送跨域请求,服务器端还必须设置一个名为**Access-Control-Allow-Headers**的**Header**,将它的值设置为**Content-Type**,表明服务器能够接收到前端发送的请求中的**Content-Type**属性并使用它的值。否则第二次请求也是发不出去的,浏览器console会报错,并提示你服务器没有设置Access-Control-Allow-Headers。
java代码如下:
httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept");httpResponse.setHeader("Access-Control-Allow-Methods", "POST");httpResponse.setStatus(200);httpResponse.setContentType("application/json");
所以简单做个demo,不跨域的如下:
$('.btn').click(function() {$.ajax({url: 'http://localhost:8081/api.json',type: 'POST',dataType: 'json',contentType: 'application/json',data: JSON.stringify({a: [{b:1, a:1}]}),success: function(res) {}})});
请求信息如下:

如上可以看到json格式提交的数据会显示Request Payload。
