HTTP 深入
一、HTTP 无状态特性的 解决方案
-
场景: HTTP协议无状态是 HTTP最初的特点之一;但随着技术和实际需求的发展,前后端交互需要承前启后,HTTP无状态的特性严重阻碍了一些应用程序的实现
-
状态保持技术: Cookie 、Session
-
应用: 用户登录保持、用户行为跟踪 等
1. Cookie ---> 存储在客户端
-
概述:
-
Cookie 实际上是存于用户硬盘的一个文件 / 浏览器的进程中的会话Cookie
-
这个文件 / 会话Cookie 通常 对应于一个域名,当浏览器再次向服务器发起请求的时候,浏览器把网址和Cookie一起提交给服务器,服务器以此来辨别该用户状态
-
-
Cookie 的类别:
-
会话Cookie:没有设置过期时间,则Cookie存在于浏览器的进程中;会随着浏览器的关闭,Cookie失效
-
硬盘Cookie:设置了过期时间,则Cookie存到硬盘上;超时后 Cookie失效
-
-
Cookie 的属性(了解):
- name:该Cookie的名称,Cookie一旦创建,名称便不可更改。
- value:该Cookie的值,Cookie中记录的信息内容。
- expire:Cookie失效时间,单位秒
- path:该Cookie的使用路径。
- domain:可以访问该Cookie的域名。
- secure:是否仅使用安全的HTTPS协议传输,默认为0
- Httponly:是否仅通过HTTP协议传输,默认为0
-
Cookie 的应用场景:
-
(1)自动登录: 如果不想用户每次登录网站的时候都输入用户名和密码,只要勾选记住登录名和密码,就可以把用户名和密码写入Cookie中,下次访问网站的时候,网站页面的脚本可以读取这个信息,自动把用户名和密码填写上去,方便用户
-
(2)跟踪 用户行为: 创建用户浏览内容的Cookie,然后就可以根据用户的浏览内容定制用户喜欢的内容,当用户下次进入的时候,服务器就可以把用户喜欢的内容推荐给用户,以达到留住用户的目的
-
(3)记录PV: Cookie中有专门的值记录用户的访问次数,当用户再次访问的时候,Cookie会将此值加1并输出
-
-
同源HTTP请求 携带Cookie:
-
同源请求 会自动携带 Cookie
-
跨域请求 不会携带Cookie, 解决方案如下:
-
// 原生ajax请求方式:
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://xxxx.com/demo/b/index.php", true);
xhr.withCredentials = true; //支持跨域发送Cookies
xhr.send();
// jquery的ajax的post方法请求
$.ajax({
type: "POST",
url: "http://xxx.com/api/test",
dataType: 'jsonp',
xhrFields: {
withCredentials: true
},
});
- JS 操作Cookie: js-cookie
2. Session ---> 存储在服务端
-
概述:
-
Session 可理解为 浏览器的一个会话;其作用于会话范围内,记录每个客户端的访问、操作状态,以便于跟踪记录每个客户端的操作状态
-
Session 实际上是一块在 服务器开辟的内存空间,存储了 Session 对象(存储着用户的信息),每个客户端的 Session 都是单独存储的
-
-
Session 特点:
-
存储在 服务端,可以存储任意类型的数据
-
关闭浏览器,一个Session会话结束,但 服务器上的Session对象没有消失;因为 服务器不知道浏览器有没有被关闭
-
-
SessionId 来实现跟踪用户状态
-
(1)基于 Cookie 传递 SessionId: 用户登录后,服务端会将 SeeesionId 置于响应头中返回,浏览器将 SessionId 存储到 Cookie中,再次访问同源请求时,携带 Cookie,服务端就会根据Cookie中的Session ID返回已经存在的Session
-
(2)基于 URL 传递 SessionId: Cookie 在浏览器中可以被禁用,这时就需要借助 URL QueryString 来传递 SessionId
-
(3)基于 隐藏域 传递 SessionId: 一个表单元素,表单提交的时候,也可以把这个元素的内容提交到服务器中去,因为它是隐藏的,所以,我们可以用它来保存一些不需要用户看到的数据
<input type="hidden" name="tc_id" value="{{tc_id}}">
-
-
Session 的应用场景:
-
(1)登录状态保持: 用户登录后,服务器返回 SessionId(在服务器设置过期时间),浏览器将 SessionId置于 Cookie中(Cookie的过期时间被设置 === Session的过期时间,不用手动创建Cookie,因为服务器在响应头中 有
set-Cookie
字段,浏览器会识别,自动创建Cookie),每次访问时携带 Cookie;服务器将根据 SeeeionId 判断该 用户的Session是否过期,若没过期,用户就登录状态一直保持 -
(2)未登录用户 记忆购物车: 未登录的用户添加 A、B、C 商品到购物车, 服务端会响应一个SessionId,服务器存储的 Session中记录了,该用户购物车中有 A、B、C 商品;用户再次浏览网站时,携带 Cookie 发送请求,服务器将 该用户购物车中 商品情况一同返回
-
-
Session 劫持:
二、TCP协议
1. 区分 HTTP协议、TCP协议
-
概述: TCP协议对应于传输层,而HTTP协议对应于应用层;Http协议是建立在TCP协议基础之上的(HTTP/1.0和HTTP/1.1都把TCP作为底层的传输协议)
-
协作过程: 当浏览器需要从服务器获取网页数据时,会发出一次Http请求;Http会通过TCP建立起一个到服务器的连接通道,请求完毕后,Http会立即将TCP连接断开;所以说HTTP请求 是短连接的
-
优化 HTTP短连接: 随着页面的复杂呈现,每次请求都需要建立一次 TCP连接,就显得非常低效;从HTTP/1.1起,默认都开启了
Keep-Alive
,保持连接特性;HTTP请求结束后,TCP连接并不会立即断开,到了预设时间点后再断开
2. TCP连接
-
场景: 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接 时它们可以释放这个连接,连接的建立是需要三次握手,而释放则需要4次挥手
-
TCP连接的建立与终止 示意图如下:
-
TCP建立的三次握手:
-
发送端发送一个SYN报文段(SYN位被置位),SYN中包含TCP目的端口和发送端的初始序列号(图中ISN(c)),同时携带着TCP选项数据。
-
接收端收到发送端连接请求后,接收端发送自己SYN报文段(包含ISN(s)),同时对发送端的SYN进行确认,如前所述,接收端发送的ACK是ISN(c)+1。此时ACK位与SYN位都被置位。接收端发送SYN+ACK到发送端。
-
发送端接收到接收端的SYN+ACK数据后,对ISN(s)进行确认,发送ACK为ISN(s)+1的报文段给接收端。
-
-
TCP断开的四次握手:
-
TCP协议规定通过发送一个FIN段(FIN被置位)来发起关闭操作,图3中发送端发送FIN段给接收端,告知它数据已发送完毕,请求断开TCP连接。同时FIN报文段还包含着对最近收到的数据进行ACK。
-
接收端接收端FIN报文段后,对FIN进行确认,发送ACK=k+1给发送端。
-
接收端将连接关闭发送给上层应用程序,由应用程序发起连接关闭操作。此时接收端由被动关闭连接壮成主动,并发送FIN报文段给发送端。报文的序列号为L(这里也可看出上一步骤中发送ACK序列号也为L,因为ACK不占用序列号,所以这里的FIN的序列号也为L)。
-
发送端接收到FIN后,发送回ACK给接收端后,TCP连接终止。如果FIN丢失,发送FIN的那端需要重新发送FIN,知道接收到ACK为止
-
三、DNS解析服务
-
概述:
- DNS解析服务 通过域名 与 IP之间的映射关系;将域名解析成IP地址
-
DNS 解析过程:
-
(1)先查看本机缓存有没有该域名的记录;若没有,就去查看本机的 host 文件有无该域名;若没有,就进行如下查询:
-
(2)本地DNS域名服务器 发送请求,一层一层查找,直到找到 目标服务器(哪台服务器行有要查找的域名),并将目标服务器地址 返回给本地DNS域名服务器
-
(3)本地DNS域名服务器 发送请求到目标服务器,目标服务器返回 该域名对应的解析
-
(4)本地DNS域名服务器 获取该解析后,返回给主机,解析完成
-
// 以解析 `xiaoxiaoguo.cn` 为例
// 查看本机的缓存有无该域名记录,如果没有,查看本机的host文件有无该域名记录,如果没有,则发个请求到本地DNS服务器
// 本地DNS服务器收到请求后,查看是否有该域名的解析,如果有,返回解析记录给主机,如果没有,则请求根域名服务器
// 根域名服务器收到请求后,返回该域名对应的顶级域名服务器,比如这次请求返回.cn的服务器地址
// 本地域名服务器接到顶级域名服务器地址后,向该顶级域名服务器请求
// 顶级域名服务器返回该域名的权威服务器地址,比如这次返回xiaoxiaoguo.cn对应的权威服务器地址
// 本地域名服务器获得该地址后,发请求到该域名的权威服务器
// 权威服务器返回该域名对应的解析
// 本地域名服务器获取该解析后,返回给主机,解析完成
四、HTTP 缓存机制
1. 缓存 存储策略
-
作用: 客户端接收到响应头中的信息,确定 Http 响应内容 是否可缓存到客户端
-
响应头中的 Cache-Control字段: 对应的值如下
- public:表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存
- private:表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)
- no-cache:强制所有缓存了该响应的缓存用户,在使用已存储的缓存数据前,发送带验证器的请求到原始服务器
- max-age:缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)
- no-store:缓存 不应存储 有关客户端请求或服务器响应的任何内容
2. 缓存 过期策略
-
作用: 客户端 来确定 缓存是否过期,过期的话就需要重新发请求获取数据
-
Expires 指名了缓存数据有效的绝对时间,告诉客户端到了这个时间点(比照客户端时间点)后本地缓存就作废了,在这个时间点内客户端可以认为缓存数据有效,可直接从 缓存中加载展示
Cache-Control:public/private(这里不太确定具体哪个)
Expires:当前客户端时间 + maxAge
- 特殊: 但有些情况,即使本地缓存已过期,还会被再次使用;因为:缓存对比策略 优先级要高于 缓存过期策略
3. 缓存 对比策略
-
作用: 客户端发送数据标识(时间戳)给服务端,服务端 来对比客户端的数据是否失效,来决定是否要重发数据
-
过程: 客户端访问支持时间戳的接口,会接收到服务端的时间戳,每次访问该接口都会带上时间戳访问;服务端先查看请求头中有没有时间戳( If-Modified-Since、If-None-Match),如果判断标识仍然有效,则返回304告诉客户端取本地缓存数据来用即可;若时间戳失效则返回200 并 重新发数据
五、 HTTP 长连接、短连接、长轮询、短轮询
-
解决方案: Keep-Alive功能使客户端到 服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立 或 重新建立连接
六、 HTTPS 协议
1. 了解 HTTP 的缺点
-
HTTP传输的数据是 未加密的(明文),内容可能会被窃听
-
HTTP协议 不验证通信方的身份,有可能遭遇伪装
-
无法证明报文的完整性(准确性),可能接收到的报文是 被篡改过的
2. TLS/SSL 协议
-
TLS/SSL 协议 安全传输层协议(Transport Layer Security),是介于TCP和HTTP之间的一层安全协议
-
SSL的位置:
- SSL 介于应用层和TCP层之间:应用层数据不再直接传递给传输层,而是传递给SSL层,SSL层对从应用层收到的数据进行加密,并增加自己的SSL头
3. HTTPS 协议
- 概述: HTTPS 是 HTTP的升级版本,HTTPS 更安全;HTTP 通信接口部分用 SSL/TLS 协议代替
-
HTTPS协议的优点:
-
确定身份: 可认证用户和服务器,确保数据发送到正确的客户机和服务器
-
数据安全: 防止数据在传输过程中不被窃取、改变,确保数据的完整性
-
-
HTTPS协议的缺点:
-
更占用CPU: 相比HTTP协议,HTTPS协议会使页面的加载时间延长近50%;
-
影响缓存,增加数据开销和功耗
-