前言
最近花了一个多月的时间读完了HTTP权威指南,虽然这本书已经出很多年了但是其中很多内容并不过时值的深度阅读,读完之后有很大的收货,在这个过程中进行了许多精华的总结,今天来分享一下,希望对看到的你有所收获
HTTP五层模型
1.http
应用层
2.TCP
传输层
3.IP
网络层
4.网络特有的链路接口 数据链路层
5.屋里网络硬件 物理层
代理与网关对比
1.代理连接的是两个或多个使用相同协议
的应用程序
2.网关连接的则是两个或多个使用不同协议的端点
,网关扮演的协议转换器
的角色,即时客户端和服务器使用的是不同的协议,客户端也可以通过它完成与服务器之间的事务处理
区分强缓存是否命中
HTTP
没有为用户提供一种手段来区分响应的数据是来自缓存的还是原始服务器的。在这两种情况想下响应码都是200 OK
,但是有些商业代理会加一写信息
1.第一种情况在响应体的首部有个Via字段
有些商业代理会在该字段中说明缓存信息客户端可以根据这个做区分
2.第二种情况就是使用Date首部
将响应体中的Date首部
与当前时间进行比较,如果响应时期较早那么数据可能就来自缓存
HTTP识别用户
在
http
中交互的事务通常是没有状态的在历史的发展过程中有一下几种阶段来记录客户端和服务端交互的状态
1.承载用户信息的HTTP
首部
首部名称 | 首部类型 | 描述 |
---|---|---|
From | 请求 | 代表用户的E-mail 地址 |
User-Agent | 请求 | 用户的浏览器软件 |
Referer | 请求 | 用户是从这个页面依照链接跳转过来的 |
Authorization | 请求 | 用户名和密码 |
Client-IP | 扩展(请求) | 客户端的IP 地址 |
X-Forwarded-For | 扩展(请求) | 客户端的IP 地址 |
Cookie | 扩展(请求) | 服务器产生的ID 标签 |
2.客户端IP地址
跟踪,通过用户的IP地址
对其进行识别
3.用户登录,通过认证方式
来识别用户
4.胖url,一种在url
中嵌入识别信息的技术
5.cookie
,一种强大且高效的持久身份识别技术
承载用户信息首部的操作现在基本已经就不用了,因为针对用户没办法精确的识别是同一个用户因为存在更换客户端比如换个手机之类的
SSL握手过程
1.交换协议版本号
2.选择一个两端都了解的密码
3.对两端的身份进行认证
4.生成临时的会话秘钥,以便加密信道
内容编码类型
HTTP
定义了一些标准的内容编码,并允许用户扩展编码的形式增添更多的编码由互联网号码分配机构(INAN)
对各种编码进行标准化,它给每个内容编码算法分配了唯一的代号。Content-Encoding
首部就用这些标准化的代号来说明编码时使用的算法
Content-Encoding值 | 描述 |
---|---|
gzip | 表明实体采用Uzip 码 |
compress | 表明使用采用Unix 文件压缩操作 |
deflate | 表明实体是用zlib 的格式压缩的 |
identity | 表明没有对实体进行编码。当没有Content-Encoding 首部时,就默认为这种情况 |
gzip、compress
以及deflate
编码都是无损压缩算法,用于减少传输报文的大小,不会导致信息损失。这些算法中,gzip
通常是效率最高的,使用范围最广
Content-length对于长连接的作用
如果响应通过持久链接传送数据就可能有另一条
HTTP
响应紧随其后,客户端通过Content-Length
首部就可以找到报文在何处结束,下一条报文从何处开始。因为是持久链接,客户端无法依赖链接关闭来判断报文的结束。如果没有Content-Length
首部,HTTP
应用程序就不知道某个实体在哪里结束,下一条报文从哪里开始
范围请求
常见的场景假设你正在通过慢速的调节器连接下载最新的热门软件,费劲巴拉的下载了四分之三,结果因为一个网络故障,
啪的一下很快喔
,连接断了,本来已经等了很久而现在还要从头再来(以前下载游戏的时候体验过这种感觉真的很崩溃😒),如果我们能做到从断的地方在继续下载剩余的就比较爽了
我们可以使用范围请求
HTTP
客户端可以通过请求获取失败实体的一个范围或者一部分,来恢复下载该实体。当然这有一个前提,那就是从客户端上一次请求该实体到这次发出范围请求的时段内,该对象没有改变过,主要是利用HTTP首部
字段Range
进行范围请求值的类型是字节,比如:Range: bytes=4000-
的意思是客户端请求文档开头4000字节
之后的部分(不需要给出结尾字节数,因为不知道具体文档的大小)
但是并不是所有服务器都可以接受范围请求 ,但很多服务器可以。服务器可以通过在响应中包含Accept-Range
首部的像是告知客户端说明可以接受范围请求,这个首部就是计算范围的单位,通常以字节计算,例如下面这样👇🏻
Accept-Range:bytes
具体操作流程可以看下面例子🌰
Vary首部
有一种情况是需要根据
HTTP首
部来订制返回不同的客户端需要的内容这就需要Vary首部
,在Vary首部
中列出了所有客户端请求的首部,服务器可以用这些首部来指定文档或产生文档内容,例如客户端想要的文档需要根据机型来决定,就需要在Vary
中放入User-Agent
,看下面例子
区分客户端访问的是代理还是实际服务器
对于客户端如果想知道当前访问的请求是来自代理服务器还是实际服务器,可以通过报文中的
url
来决定
客户端向web
服务器发送请求,可以看到请求的不是完整的url
只有一个index.html
GET /index.html HTTP/1.0
User-Agent: SuperBrowser v1.3
客户端向代理发送请求时,请求中则包含完整的URL
GET http://www.marys-antiques.com/index.html HTTP/1.0
User-Agent: SuperBrowser v1.3
那么问题来了,为什么会有两种不同的格式一种用于服务器一种用于代理呢?看👇🏻
在最开始的
HTTP
设计中,客户端会直接与单个服务器对话。不存在虚拟主机
,也没有为代理制定什么规则。单个服务器都知道自己的主机名
和端口
,所以为了避免冗余信息就没必要发送主机名和端口等,但是代理出现之后,使用部分url
就有问题了。代理需要知道目标服务器的名称,这样它们才能正确的与自己服务器链接。基于代理的网关
要知道URL
的方案才能正常连接到FTP资源和其他方案上去。HTTP/1.0
要求代理请求发送完整URL
,解决了这个问题,但它为服务器请求保留部分URL
的形式
DNS实现负载均衡
DNS轮转
是最常见的重定向技术之一也是最简单的重定向技术之一。DNS轮转
使用了DNS主机名
解析中的一项特性,在web服务器
集群中实现负载均衡
,实际原理是对主机名下的所有IP
进行轮转
-
主机下面有
10个IP
会随着访问一个一个向后移动 -
一个
IP
访问完成之后就会把第一个ip
放到最后面 -
次访问的就是第二个
IP
,之后访问完成在把第二个IP
放到最后面 -
依次按照顺序访问就被称为轮转
-
想象为一个队列从队头拿出来用完在放到队尾等待下次使用
状态码分类
总体范围 | 已定义范围 | 类别 |
---|---|---|
100-199 | 100-101 | 信息 |
200-299 | 200-206 | 成功 |
300-399 | 300-305 | 重定向 |
400-499 | 400-415 | 客户端错误 |
500-599 | 500-505 | 服务端错误 |
来看几个常见的状态码👇🏻
状态码 | 描述 |
---|---|
200 | 服务器成功处理请求 |
204 | 响应报文包含一些首部和一个状态行,没返回主体内容 |
206 | 返回部分内容代表部分请求成功 |
301 | 永久重定向根据响应信息首部Location 进行跳转 |
302 | 临时重定向也会根据响应信息首部Location 进行跳转,并且会缓存当前的URL |
304 | 协商缓存必并且会更新本地强缓存 |
305 | 需要使用代理访问 |
307 | 重定向类似302 不过是给http/1.1 用的 |
400 | 客户端请求错误 |
401 | 没有权限可能是token 过期 |
403 | 服务器拒绝请求从根本上就没有权限 |
404 | 找不到要访问的目标URL |
405 | 资源被禁止访问 |
408 | 请求超时 |
500 | 服务器处理错误 |
502 | 网关故障,多半是作为网关或者代理的时候上游的服务器处理错误没办法正常返回 |
504 | 网关超时 与408 类似,但是响应是来自网关或者代理的上游服务器 |
505 | 服务器不支持当前传输的协议 |
结束
书中自有颜如玉,书中自由黄金屋,老话总是没错的,多谢欣赏