HTTP 深入

一、HTTP 无状态特性的 解决方案

  • 场景: HTTP协议无状态是 HTTP最初的特点之一;但随着技术和实际需求的发展,前后端交互需要承前启后,HTTP无状态的特性严重阻碍了一些应用程序的实现

  • 状态保持技术: Cookie 、Session

  • 应用: 用户登录保持、用户行为跟踪 等

  • 概述:

    • 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  
    },
});

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%;

    • 影响缓存,增加数据开销和功耗

posted @ 2018-04-19 17:14  执着的程序员~  阅读(506)  评论(0编辑  收藏  举报