W3CAPI 在线教程 | 菜鸟教程_LOGO
文档目录
文档目录
我的书签
 

计算机网络

HTTP协议中的Content-Type

对于HTTP协议来说,好多不是计算机网络专业的朋友来说不是很熟悉,特别是针对其中的一些语法也感觉莫名其妙,其实HTTP协议中也是有一定的语法规则的(其实就是一些硬性规定,比如我们日常生活中自然语言的一些规定:好样的的是褒义词,笨蛋是贬义词),Content-Type就是HTTP协议中用来规定一些文件类型的,传输过程中根据设置好的Content-Type就可以知道要处理的内容是什么类型

jesen
1
2020-03-18 08:06:30

HTTP中的Content-Type是什么?

一、Content-Type在HTTP中的定义
    HTTP请求中的Content-Type是用来指定请求或者响应的内容类型,也叫做MediaType(即是Internet Media Type,互联网媒体类型;也叫做MIME类型)告诉浏览器或者相关客户端如何显示或处理加载的数据(比如服务器响应时将Content-Type的值设置为text/html,那么浏览器或者客户端就可以将此内容识别为html类型的内容,就可以解析为网页了),此属性的值可以查看MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)的类型来使用(此标准中定义了一系列标识,来表示内容的类型是什么,以便让互联网中的设备进行识别,因为所有相关的互联网客户端程序已经按照此标准实现了内容类型的识别,类似于现实世界中约定俗称的规定:红灯停,绿灯行等),关于MIME相关的信息,可以查阅本系统中相关的文档

二、语法结构
Content-Type: text/html; charset=utf-8
Content-Type: multipart/form-data; boundary=something
可以看出来语法结构为:type/subtype(;parameter=value) 不允许空格存在,对大小写不敏感,但传统都是小写
  1. type 主类型,MIME中规定的任意标识符,如text,如果是*号代表所有
  2. subtype 子类型,MIME中规定的任意标识符,如html,如果是*号代表所有  
  3. parameter 可选,一些参数,如Accept请求头的q参数, Content-Type的 charset参数等
  4. charset:是指定字符编码的标准,常见的有"ISO-8859-1"、"UTF-8"、"GB2312“,”ASCII“等
  5. boundary:多用于上传文件时使用,用于分割数据

type包括两种类型:独立类型和Multipart类型
  • 独立类型
独立类型从名字上可以看出来,只表示了一个单独的文件或者媒体的类型,表示组成内容的形式是独立存在的,比如一个HTML页面,一个视频文件,如下为常用的独立类型:
Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的
Application:用于传输应用程序数据或者二进制数据,例如application/octet-stream,application/pdf,application/pkcs8,application/zip
Image:图像或图形数据,包括位图和矢量图像以及动画图像,例如image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon
Audio:用于传输音频或者音声数据,例如audio/mpeg, audio/vorbis
Video:用于传输动态影像数据,可以是与音频编辑在一起的视频数据格式,例如video/mp4
  • Multipart类型
Multipart类型表示此内容由多个部分组成的,且经常有不同的MIME类型(也就是由多个独立类型的内容组成的)。也可以用来表示属于相同事物的多个且独立的文件,这些独立的文件构成一个复杂的文档。在电子邮件场景中常见,如下为常用的Multipart类型
Multipart:用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据,由多个不同MIME类型组件构成的数据,例如 multipart/form-data(由多种内容类型进行传输,可能既包括多媒体内容,又包括数据内容)
Message:一个包括多种内容类型的消息,常用于下面的场景,例如指明一个邮件包含转发信息或者在多种信息的情况下,允许以chunk的形式发送数据量很大的信息。包括message/rfc822和message/partial,一般用于包装一个E-mail消息

常用的Content-Type

一、application/x-www-form-urlencoded
主要用于form表单中,<form enctype=""> 中默认的enctype,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式),一般用于简单的数据(键值对的数据结构,数据被编码成以 '&' 分隔的键-值对, 同时以 '=' 分隔键和值. 非字母或数字的字符会被 percent-encoding: 这也就是为什么这种类型不支持二进制数据的原因)进行传输;很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 的Ajax,Content-Type 默认值就是 [application/x-www-form-urlencoded;charset=utf-8]
 
二、application/json
主要用于POST请求以JSON的格式向服务发起请求,或者服务器向客户端返回JSON格式的内容进行响应,服务端接收到数据后对JSON进行解析拿到所需要的数据。现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于JSON规范的流行,除了低版本IE 之外的各大浏览器都原生支持JSON.stringify,服务端语言也都有处理JSON的函数,使用 JSON已经可以一路畅通了

JSON 格式支持比键值对复杂得多的结构化数据,这一点也非常有用,当需要提交比较复杂的数据结构的时候,比如多层数据的嵌套就可以利用json很好地解决了
以下是利用jQuery的ajax来发送json请求的代码:
$.ajax({
     method:"post",
     url:"http://www.w3capi.com/test",
     contentType:"application/json;charset=utf-8",
     data:{
         'title':'test',
         'sub' : [1,2,3]
     }
});

最终发送请求的格式为:

POST http://www.w3capi.com/test HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}
使用json,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口;各大浏览器如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示 JSON 数据,非常友好。但也有些服务端语言还没有支持这种方式,例如 php 就无法通过 $_POST 对象从上面的请求中获得内容。这时候,需要自己动手处理下:在请求头中 Content-Type 为 application/json 时,需要从 php://input 里获得原始输入流,再 json_decode 成对象。一些 php 框架已经开始这么做了 

三、multipart/form-data

在表单中进行文件上传时,就需要使用该格式,如下:
<form action="/Index/test" enctype="multipart/form-data" method="post">
    <input type="file" name="file_data" />
    <input type="submit" value="测试提交" />
</form>
生成的HTTP请求为:
POST http://www.w3capi.com/Index/test HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryusAwgDgO8X0WGuvH
------WebKitFormBoundaryusAwgDgO8X0WGuvH 
Content-Disposition: form-data; name="file_data"; filename="test_img.jpg" 
Content-Type: image/jpeg 

------WebKitFormBoundaryusAwgDgO8X0WGuvH--

根据请求可以看到,在Content-Type中声明了内容的类型为multipart/form-data,而后紧跟 boundary 参数的值 用于分割不同的字段,为了避免与正文内容重复,消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 ------boundary值 开始,紧接着内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 ------boundary值 结束。关于 mutipart/form-data 的详细说明,请前往 RFC1867 查看。
 

相关提问
敬请期待