一. 基础概念
HTTP 特点
- 简单快速:请求服务时,只需传送请求方法和路径
- 灵活:允许传输任意类型的数据对象,由 Content-Type 标记
- 无连接:服务端处理完请求就断开连接
- 无状态:意味着每个请求都是独立的,如果后续处理需要前面的信息,则它必须重传
HTTPS
- HTTPS 就是在 HTTP 下加入了 SSL 层,从而保护了交换数据隐私和完整性,提供对网站服务器身份认证的功能
-
功能:
- 通过证书等信息确认网站的真实性:对网站进行认证,给予它独一无二的身份证明
- 建立加密的信息通道:签发的数字证书可以通过加密技术(对称加密与非对称加密)对我们在网上传输的信息进行加密
- 验证数据内容的完整性:当数据包经过无数次路由器转发后会发生数据劫持,黑客将数据劫持后进行篡改。开启HTTPS后黑客就无法对数据进行篡改,就算真的被篡改了,我们也可以检测出问题
持久连接 Keep-Alive
- connection: Keep-Alive 使客户端到服务器端的连接持续有效,避免了建立或者重新建立连接,超过 Keep-Alive 规定的时间,意外断电等情况除外
- 请求 1 -> 响应 1 -> 请求 2 -> 响应 2
- HTTP 1.1
管线化
- 通过持久连接完成
- 请求 1 -> 请求 2 -> 请求 3 -> 响应 1 -> 响应 2 -> 响应 3
- 只有 GET 和 HEAD 可以进行管线化,POST 则有所限制
- HTTP 1.1
GET 和 POST 区别
- GET 请求在 URL 中传送的参数是有长度限制的,而 POST 么有
- GET 比 POST 更不安全,因为参数直接暴露在 URL 上,所以不能用来传递敏感信息
- GET 参数通过 URL 传递,POST 放在 Request body 中
- GET 在浏览器回退时是无害的,而 POST 会再次提交请求
- GET 产生的 URL 地址可以被收藏,而 POST 不可以
- GET 请求会被浏览器主动缓存,而 POST 不会,除非手动设置
- GET 请求参数会被完整保留在浏览器历史记录里,而 POST 中的参数不会被保留
- GET 请求只能进行 url 编码,而 POST 支持多种编码方式
常用状态码
- 200 OK:请求已正常处理
- 204 No Content:请求处理成功,但没有任何资源可以返回给客户端
- 301 Moved Permanently:永久重定向
- 302 Found:临时性重定向
- 304 Not Modified:资源未修改,不返回资源,允许客户端访问缓存资源
- 400 Bad Request:请求参数有误
- 401 Unauthorized:要求用户身份认证要求
- 403 Forbidden:服务器理解请求,但拒绝执行请求
- 404 Not Found:服务器上没有请求的资源。路径错误等
- 408 Request Time-out:请求超时
- 500 Internal Server Error:服务器内部错误
二. 三次握手与四次挥手
三次握手
假如是两次握手
1. C:喂喂喂,我是 C,你听的到吗?
2. S:在在在,我能听到,我是 S,你能听到我吗?
3. C:(听到了,老子不想理你)
4. S:喂喂喂?听不听到?我 X,对面死了,我挂了。。
假如是四次握手
1. C:喂喂喂,我是 C,你听的到吗?
2. S:在在在,我能听到,我是 S,你能听到我吗?
3. C:听到了,你呢?你能听到吗?
4. S:??你是智障?我不是说了我能听到吗,不想跟 xx 说话。。。
三次握手
1. C:喂喂喂,我是 C,你听的到吗?
2. S:在在在,我能听到,我是 S,你能听到我吗?
3. C:听到了。我们今天去钓鱼吧。。balabala
总结
1. 第一次握手,C 端发送 S 端接收到,证明了 C 端的发送能力
2. 第二次握手,S 端发送 C 端接收到,证明了 S 端的接收能力和发送能力
3. 第三次握手,C 端发送 S 端接收到,证明了 C 端的接收能力
4. 在可靠的同时,还要考虑性能和时间问题,所以三次握手最合理
四次挥手
全双工
A 和 B 可以互相通信,类比发短信,同一时间双方都可以发信息给对方,互不影响
单双工
A 和 B 只能单向通信,类比打电话,同一时间只能一人说话,另一人听,如果两人一起说话,那谁都听不清楚了,没有意义
四次挥手
1. C:不好意思 S,我这边需要关闭连接了,你准备一下?
2. S:好的 C,我收到你的关闭信号了,我还有数据没发好,你等我下。
3. S:C 老弟,我可以关闭了,给你最后说一下,等下你回应我的话,我就直接关了;
4. C:好的老哥,我回应你一下,你收到就关闭吧,不用理我
5. S:(收到 ack 信息,直接就关闭了),此过程不产生数据的交互,不算挥手次数
6. C:等待 2MSL(最大报文段生存时间)后,S 没东西给过来,我也关了;
与三次握手的区别
四次挥手的中间两次挥手相当于把三次握手的中间一次握手拆分为两次
为什么 C 端需要等最大报文生存时间后才能关闭?
担心网络不可靠而导致的丢包,超过了最大等待时间的话,就算收不到也没用了,所以就可以关闭了。
三. 缓存
Expires(强缓存)
- HTTP 1.0 字段,表示缓存到期时间,一个绝对时间
Expires: Thu, 10 Nov 2020 08:45:11 GMT
- 缺点:若用户修改本地时间,则可能导致浏览器判断缓存失效
Cache-control(强缓存)
- HTTP 1.1 字段,表示资源缓存的最大有效时间(秒),在该时间内,客户端不需要向服务器发送请求,优先级高于 Expires
Cache-control:public, max-age=2592000
- max-age:即最大有效时间
- s-maxage:用于代理缓存(比如 CDN 缓存),优先级大于 max-age
- must-revalidate:如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效
- no-cache:浏览器缓存内容,但不直接使用,使用时向服务器发请求确认
- no-store:不进行任何缓存
- public:所有的内容都可以被缓存(包括客户端和代理服务器, 如 CDN)
- privite:所有的内容只有客户端才可以缓存(默认值)
- max-age=0, must-revalidate 和 no-cache 等价
Last-Modified & If-Modified-Since(弱缓存)
- 服务器通过 Response Headers 的 Last-Modified 字段告知客户端,资源最后一次被修改的时间
Last-Modified: Mon, 10 Nov 2020 09:10:11 GMT
- 下一次请求相同资源时,浏览器从自己的缓存中找出“不确定是否过期的”缓存。因此在 Request Headers 中将上次的 Last-Modified 的值写入到请求头的 If-Modified-Since 字段
If-Modified-Since: Mon, 10 Nov 2020 09:10:11 GMT
- 服务器会将 If-Modified-Since 的值与 Last-Modified 字段进行对比。如果相等,则表示未修改,响应 304,继续返回 Last-Modified 字段;反之,则表示修改了,响应 200 状态码,并返回数据以及新的 Last-Modified 字段
-
缺点:
- 某些服务器无法获取精准时间
- 如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为它的时间单位最低是秒
- 如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用
Etag & If-None-Match(弱缓存)
- Etag 存储的是文件的特殊标识(一般都是 hash 或 MD5 生成的),服务器存储着文件的 Etag 字段,
ETag: "asj1jbasdbb4skdbk-ajs"
- 流程与 Last-Modified & If-Modified-Since 一致
If-None-Match: "asj1jbasdbb4skdbk-ajs"
- Etag 的优先级高于 Last-Modified
- 更为严谨,文件变换及 Etag 变化
分级缓存策略
- 200 from cache:最底层,由 Expires、Cache-control 控制(Cache-control 优先级大于 Expires),若命中缓存则直接读取,若没有命中,则进入下一状态
- 304:这一层由 Last-Modified、Etag 控制(Etag 优先级大于 Last-Modified),若服务器校验通过,返回 304 及旧的 Last-Modified、Etag 字段,浏览器读取缓存;若服务器校验不通过,进入下一状态
- 200:若服务器校验不通过,或用户强制刷新页面,则返回 200 和文件以及新的 Last-Modified、Etag 字段,浏览器更新缓存
总结
- Expires、Cache-control、Last-Modified & If-Modified-Since 均以时间秒为维度,而 Etag & If-None-Match 则是以文件为维度,所以 Etag 最为严谨,文件变化 Etag 就会变化
- 优先级:Cache-control > Expires > Etag > Last-Modified
四. 参考文章
一文读懂前端缓存
本文大部分为自己总结,部分示例时参考了一些文章,但因误删了浏览器历史记录,导致部分参考文章无法找回,若有知情者请与我联系,我会补上原文链接。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。