HTTP 报文分为请求报文与响应报文。
当客户端发出一个请求,服务器就会做出响应,返回一个响应报文。无论是请求报文还是响应报文都是由三部分组成:Line ,header,body。
<Request Method>空格<Request URL>空格<Http版本号>
<Key>:<Value>
<Key>:<Value>
不可缺少的空行
<Entity Body>
请求行是由三部分组成:
请求头是由键值对组成,key与value之间以":"进行分隔,最后以CRLF表示结束,比如Content-Length:56,这里的Content-Length表示key,value是56。 HTTP头部字段使用非常灵活,我们可以使用已有的头部,还可以自定义头部。但是再使用头部字段需要注意以下几点:
又称为请求体,与请求正文。
<Http Version>空格<Status Code>空格<Reason Phrase>
<Key>:<Value>
<Key>:<Value>
不可缺少的空行
<Entity Body>
称为服务器响应的状态。用户返回客户端对服务器请求的结果。 状态行也是三部分组成:
格式与意义与请求报文一一致。比如:Header有的只能用在响应报文中,有的只能用在请求报文中,有的两者皆可用。
又称之为响应体,就是客户端请求服务器返回的结果内容,可以是文本、音频、视频等等。
首都字段有 4 种类型:分为通用首部字段、请求首部字段、响应首部字段和实体首部字段。
HTTP首部字段将定义成缓存代理与非缓存代理,分为两种类型:
hop-by-hop
字段,则需要connection
首部字段。
逐跳首部字段有:
1.connection 2.keep-alive 3,proxy-authenticate 4.proxy-authorization 5.tralier 6.TE 7.transfer-encoding 8.upgrade
Transfer-Encoding: chunked
表示,意思是报文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)逐个发送。
分块传输也可以用于“流式数据”,例如由数据库动态生成的表单页面,这种情况下 body 数据的长度是未知的,无法在头字段"Content-Length"
里给出确切的长度,所以也只能用 chunked
方式分块发送。
"Transfer-Encoding: chunked"和"Content-Length"
这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知。字段名 | 说明 |
---|---|
Cache-Control | 控制缓存行为 |
Connection | 控制不再转发给代理的首部字段、管理持久连接 |
Date | 创建报文的日期时间 |
Pragma | 用于包含实现特定的指令 |
Trailer | 报文末端首部一览 |
Transfer-Encoding | 指定报文传输的编码格式 |
Upgrade | 升级HTTP协议 |
Via | 代理服务器相关信息 |
Warning | 错误通知 |
Accept
:用户代理可处理的媒体类Accept:用户代理可处理的媒体类A型
text/html、text\plain、text\css
等
= 图片文件:image/jped、image/png,image/gif
等video/mpeg、video/quicktime
等application/zip
等比如:Accept:text/html、application/xml;q=0.8
在媒体类型后用分号隔开,使用q来表示权重,优先级,没有指定q即为1.0,优先级最高,范围是0-1可以精确到小数后3位。
if-xxx
的请求字段,都可以成为条件请求,服务器接收到请求后,只有判断条件为真才会执行。
比如:
if-match:"123456"
会告知服务器需要匹配资源所用的实体字段值(ETag),只有if-match
与资源的ETag
值一致,才会执行请求,而if-none-match
相反,不一致才会执行请求。if-modified-since
:指定日期后,资源更新,服务器才会接收请求,否则无法接收请求。if-unmodified-since
相反,指定日期后,资源更新就无法接收请求if-range :if-range
字段值与etag
值或者更新日期时间匹配一直,就做范围请求,否则返回全体资源User Agent
:用户代理,作为访问者来代理发起请求,即Http协议里的请求方客户端。
通常浏览器在发送请求时都会带着"Accept-Encoding"
头字段,里面是浏览器支持的压缩格式列表,例如 gzip、deflate、br
等,这样服务器就可以从中选择一种压缩算法,放进"Content-Encoding"
响应头里,再把原数据压缩后发给浏览器。
通过Range来获取范围请求,并指定资源byte的范围 比如:
5001-10000字节
Range:bytes=50001-10000
5000后的全部
Range: bytes = 5000-
1300-4000,5000-10001两个范围
Range: bytes = 1300-4000,5000-10001
Range: bytes = -500;获取最后500个字节
Range:bytes = 0-0,-1;仅要第一个与最后一个字节
Range
条件请求:指的是如果客户端已经得到这部分响应,想要该响应未过期前,获取其他部分响应,常与If-Unmodified-Since
或者If-Match
头部共同使用。
比如:断点续传中,使用到条件请求,来查看服务器是否修改资源,资源是否过期;服务器资源是否在两次下载之间发生改变,如果发生了变化。通过412状态码知道发生变换,得重新获取响应。
字段名 | 说明 |
---|---|
Accept | 客户端可以接受的媒体类型 |
Accept-Charset | 客户端可以接受的字符编码集 |
Accept-Encoding | 浏览器支持服务器返回的压缩格式列表 |
Accept-Language | 浏览器可以支持的语言 |
Authorization | Web认证信息 |
Expect | 请求服务器的特定行为 |
From | 发出请求的用户邮箱地址 |
Host | 请求资源所在的服务器地址 |
If-Match | 只有请求内容与实体一样才有效 |
If-Modified-Since | 如果请求的内容在指定时间之后被修改则请求成功,未被修改返回304状态码 |
If-None-Match | 请求内容与资源ETag值不一致,相反则请求成功 |
If-Range | 如果实体未改变,发送客户端没有的部分,否则发送整个实体 |
If-Unmodified-Since | 只有在指定时间后未被修改才请求成功 |
Max-Forwards | 限制信息通过代理与网关的时间 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体字节的范围请求 |
Referer | 浏览器对来自某一页面的内容中自动添加头部 |
TE | 传输编码的优先级 |
User-Agent | Http 客户端的信息 |
字段名 | 说明 |
---|---|
Accept-Ranges | 是否接受字节范围请求 |
Age | 自源服务器发出响应(或者验证过期缓存),到使用缓存响应发出时经过的秒数 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定 URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | 向客户端提供 Web 服务的软件名称和版本号,用于帮助客户端定位问题和统计数据 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端认证信息 |
字段名 | 说明 |
---|---|
Allow | 对某网络资源的有效的请求行为,不允许则返回405 |
Content-Encoding | 服务器支持返回的压缩编码格式 |
Content-Language | 实体主体语言 |
Content-Length | 实体主体大小 |
Content-Location | 请求资源可以替代的备用另一个地址 |
Content-MD5 | 返回资源MD5校验值 |
Content-Range | 实体主体位置范围 |
Content-Type | 实体主体过期类型 |
Expires | 实体主体过期时间 |
Last-Modified | 资源最后修改的时间 |
http 状态码分为五类。
body
里的数据不是资源的全部,而是其中的一部分。并且通常还会伴随着头字段Content-Range
,表示响应报文里 body 数据的具体范围,供客户端确认,比如:Content-Range: bytes 0-200/1000
,表示此次获取的是总计 1000 个字节的前 200 个字节。If-Modified-Since
等条件请求,表示资源未修改,用于缓存控制。它不具有通常的跳转含义,重定向已到缓存的文件,也就是缓存重定向。当客户端拥有可能过期的缓存,会携带etag,时间等信息询问服务器缓存是否可用,304是告诉客户端可以复用缓存;常见的:
不常见的:
Retry-After
字段,指示客户端可以在多久以后再次尝试发送请求。