一. 基础概念
HTTP 特色
- 简单快速:请求服务时,只需传送请求方法和路径
- 灵活:容许传输任意类型的数据对象,由 Content-Type 标记
- 无链接:服务端处理完请求就断开链接
- 无状态:意味着每一个请求都是独立的,若是后续处理须要前面的信息,则它必须重传
持久链接 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 & If-None-Match 则是以文件为维度,因此 Etag 最为严谨,文件变化 Etag 就会变化
- 优先级:Cache-control > Expires > Etag > Last-Modified
四. 参考文章
一文读懂前端缓存bash
本文大部分为本身总结,部分示例时参考了一些文章,但因误删了浏览器历史记录,致使部分参考文章没法找回,如有知情者请与我联系,我会补上原文连接。服务器