最近面试总有一些回答的不太好问题,就比如昨天面试面试官问到http的请求报文有哪些,听到这个问题有点蒙,因为前端平时在工作中很少接触到报文这个名词。即使我们平时在联调接口的时候也在用报文相关的知识,但是并没有这个完整的报文的概念。面试结束后,下来查了下,在这里做下总结。
一.HTTP报文是什么
首先HTTP是全称是超文本传输协议,但是HTTP本身作为应用层协议并不负责传输的具体工作,是由TCP/UDP传输层协议进行数据传输,HTTP的核心则是传输的报文(message)内容。HTTP 协议在规范文档里详细定义了报文的格式,规定了组成部分,解析规则,还有处理策略。
HTTP报文分为两部分,请求报文和响应报文
请求报文:客户端发送请求时的 HTTP 请求信息;
响应报文:服务器响应客户端请求时发送的响应信息
二.HTTP报文的组成
HTTP 协议的请求报文和响应报文的结构基本相同,由三大部分组成:
起始行(start line):描述请求或响应的基本信息;
头部字段集合(header):使用 key-value 形式更详细地说明报文;
消息正文(entity):实际传输的数据,它不一定是纯文本,可以是图片、视频等二进制数据。
通常我们把起始行+头部字段简称为请求头或者响应头(header),消息正文称为实体(body)
HTTP 协议规定报文必须有 header,但可以没有 body,而且在 header 之后必须要有一个 空行,也就是 「CRLF」,十六进制的「0D0A」。
在这个浏览器发出的请求报文里,第一行 GET / HTTP/1.1 就是请求行,而后面的 Host、Connection 等等都属于 header,报文的最后是一个空白行结束,没有 body。
三.HTTP报文各个组成详解
1.首先是请求报文和响应报文的header分被称为请求行和状态行
请求行有三部组成:
请求方法:是一个动词,如 GET/POST,表示对资源的操作;
请求目标:通常是一个 URI,标记了请求方法要操作的资源;
版本号:表示报文使用的 HTTP 协议版本。
在这个请求行里,GET
是请求方法,/
是请求目标,HTTP/1.1
是版本号
状态行也分三部分
版本号:表示报文使用的 HTTP 协议版本;
状态码:一个三位数,用代码的形式表示处理的结果,比如 200 是成功,500 是服务器错误;
原因:作为数字状态码补充,是更详细的解释文字,帮助人理解原因。
2.头部字段
请求行或状态行再加上头部字段集合就构成了 HTTP 报文里完整的请求头或响应头,我画了两个示意图,你可以看一下。
请求头和响应头的结构是基本一样的,唯一的区别是起始行,所以我把请求头和响应头里的字段放在一起介绍。
头部字段是 key-value 的形式,key 和 value 之间用 :
分隔,最后用 CRLF 换行表示字段结束。
HTTP 协议规定了非常多的头部字段,实现各种各样的功能,但基本上可以分为四大类:
通用字段:在请求头和响应头里都可以出现;
请求字段:仅能出现在请求头里,进一步说明请求信息或者额外的附加条件;
响应字段:仅能出现在响应头里,补充说明响应报文的信息;
实体字段:它实际上属于通用字段,但专门描述 body 的额外信息。
Host
首先要说的是 Host 字段,它属于 请求字段,只能出现在请求头里,它同时也是唯一一个 HTTP/1.1 规范里要求 必须出现 的字段。
User-Agent
User-Agent 是请求字段,只出现在请求头里。它使用一个字符串来描述发起 HTTP 请求的客户端,服务器可以依据它来返回最合适此浏览器显示的页面。
但由于历史的原因,User-Agent 非常混乱,每个浏览器都自称是 Mozilla 、Chrome 、Safari ,企图使用这个字段来互相 伪装,导致 User-Agent 变得越来越长,最终变得毫无意义。
Date
Date 字段是一个 通用字段 ,但通常出现在响应头里,表示 HTTP 报文创建的时间,客户端可以使用这个时间再搭配其他字段决定缓存策略。
Server
Server 字段是 响应字段,只能出现在响应头里。它告诉客户端当前正在提供 Web 服务的软件名称
Content-Length
实体字段里要说的一个是 Content-Length ,它表示报文里 body 的长度,也就是请求头或响应头空行后面数据的长度。服务器看到这个字段,就知道了后续有多少数据,可以直接接收。如果没有这个字段,那么 body 就是不定长的,需要使用 chunked 方式分段传输。
四.总结
1.HTTP 报文结构由「起始行 + 头部 + 空行 + 实体」组成,简单地说就是「header+body」;
2.HTTP 报文可以没有 body,但必须要有 header,而且 header 后也必须要有空行;
3.请求头由「请求行 + 头部字段」构成,响应头由「状态行 + 头部字段」构成;
4.请求行有三部分:请求方法,请求目标和版本号;
5.状态行也有三部分:版本号,状态码和原因字符串;
6.头部字段是 key-value 的形式,用 : 分隔,不区分大小写,顺序任意,除了规定的标准头,也可以任意添加自定义字段,实现功能扩展;
7.HTTP/1.1 里唯一要求必须提供的头字段是 Host,它必须出现在请求头里,标记虚拟主机名。