HTTP请求中Content-Type
Content-type
MediaType,即是Internet Media Type,互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。
类型格式:
Content-Type : type/subtype(;parameter)? type
- 主类型,任意的字符串,如text,如果是*号代表所有;
- subtype 子类型,任意的字符串,如html,如果是*号代表所有;
- parameter 可选,一些参数,如Accept请求头的q参数, Content-Type的 charset参数。
例如: Content-Type: text/html;charset:utf-8;
常见的媒体格式类型如下:
text/html :HTML格式
text/plain :纯文本格式
text/xml :XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png :png图片格式
以application开头的媒体格式类型:
application/xhtml+xml :XHTML格式
application/xml :XML数据格式
application/atom+xml :Atom XML聚合格式
application/json :JSON数据格式
application/pdf :pdf格式
application/msword :Word文档格式
application/octet-stream :二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
另外一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
生产中常用的4种Content-Type
值 | 描述 |
---|---|
application/x-www-form-urlencoded | 在发送前编码所有字符(默认) |
multipart/form-data | 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。 |
application/json | 作为请求头告诉服务端消息主体是序列化的JSON字符串。除低版本的IE,基本都支持。 |
text/plain | 空格转换为 “+” 加号,但不对特殊字符编码。 |
application/x-www-form-urlencoded
HTTP中默认的提交数据的方式。
浏览器的原生 form表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):
POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
- Content-Type 被指定为 application/x-www-form-urlencoded;
- 提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。
- 很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 和 QWrap 的 Ajax 默认的Content-Type 值都是「application/x-www-form-urlencoded;charset=utf-8」。
multipart/form-data
一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须将 的 enctype设为 multipart/form-data。
注意:以上两种方式:application/x-www-form-urlencoded和multipart/form-data都是浏览器原生支持的。
application/json
application/json作为请求头,用来告诉服务端消息主体是序列化的JSON字符串,除了低版本的IE,基本都支持。服务端有处理JSON的函数,使用不会有任何麻烦。
JSvar data = {'title':'test', 'sub' : [1,2,3]};
$http.post(url, data).success(function(result) {
...
});
BASHPOST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}
注意: AngularJS 中的 Ajax 功能,默认就是application/json。
axios默认的请求头也是application/json。
text/xml
(XML只会按照按照UCS-4编码处理该文件)
即:Content-Type: text/html;charset:utf-8;
也只会按照UCS-4编码处理
POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<?xml version="1.0"?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4>41</i4></value>
</param>
</params>
</methodCall>
application/xml
(与text/xml不同,可以指定编码)
Content-type: application/xml; charset="utf-16"
前后端接口调通
总结一下上述知识:
Content-Type: application/x-www-form-urlencoded;charset=utf-8
请求体中数据(也就是请求参数)会编译成键值对发送到后端
示例:title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
Content-Type: application/json
请求体中数据以JSON字符串的形式发送到后端
{"title":"test","sub":[1,2,3]}
在实际项目开发中,由于前后端事情没有进行接口调通,很大情况就会出现。由于前端明明请求的接口及参数都是正确的,而后端没有返回数据的情况。很大原因是由于前端在请求接口时没有使用正确的Content-Type对参数进行处理。
Ajax与Axios请求的默认Content-Type
- 如JQUERY或使用原生的Ajax默认Content-Type:application/x-www-form-urlencoded;charset=utf-8
- Axios默认Content-Type: application/json
Axios接口调用示例
基于后端比较常用Content-Type:application/x-www-form-urlencoded;charset=utf-8,在使用Axios调用接口时解决参数编码方法
- 方法一:(手动编译参数)
import axios from 'Axios'
let param = new URLSearchParams()
param.append('username', 'ken')
param.append('age', '18')
axios({
method: 'post',
url: '.......',
data: param
})
// 此方法Content-Type依旧是application/json,只不过把参数手动编译成ontent-Type:application/x-www-form-urlencoded格式
(也就是说前端在调用接口请求时,无论Content-Type是怎样,后端只要接收到正确的编译数据格式也就没什么毛病)
- 方法二:(配置请求头)
//例如后端要求请求数据
Content-Type:application/x-www-form-urlencoded;charset=utf-8
//qs是axios库下包含的对象序列化工具
import Qs from 'qs'
let data = {
username : "ken",
age : "18"
}
axios({
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
},
method: 'post',
url : '......',
data : Qs.stringify(data) // 'username=ken&age=18'
});