网络相关基础
# HTTP
# http版本的比较
版本 | 内容 |
---|---|
http0.9 | 只允许客户端发送 GET 这一种请求;且不支持请求头,协议只支持纯文本;无状态性,每个访问独立处理,完成断开;无状态码 |
http1.0 | 解决 0.9 的缺点,增加 If-modify-since(last-modify)和 expires 缓存属性 |
http1.x | 增加 cache-control 和 If-none-match(etag)缓存属性 |
http2.0 | 采用二进制格式传输;多路复用;报头压缩;服务器推送 |
http3.0 | 采用 QUIC 协议,自定义连接机制;自定义重传机制;无阻塞的多路复用 |
# HTTP状态码
# 比较分类
序列 | 详情 |
---|---|
1XX(通知) | 代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。101 Switching Protocols |
2XX(成功) | 200(成功)、201(服务器创建)、202(服务器接收未处理)、203(非授权信息)、204(未返回内容)、205(重置内容)、206(部分内容) |
3XX(重定向) | 301(永久移动)、302(临时移动)、303(查看其他位置)、304(未修改)、305(使用代理)、307(临时重定向) |
4XX(客户端错误) | 400(错误请求)、401(未授权)、403(禁止)、404(未找到)、405(方法禁用)、406(不接受)、407(需要代理授权) |
5XX(服务器错误) | 500(服务器异常)、501(尚未实施)、502(错误网关)、503(服务不可用)、504(网关超时)、505(HTTP 版本不受支持) |
总括:
- 1xx:指示信息–表示请求已接收,继续处理。
- 2xx:指示成功–表示请求已被成功接收、理解、接受。
- 3xx:指示重定向–要完成请求必须进行更进一步的操作。
- 4xx:指示客户端错误–请求有语法错误或请求无法实现。
- 5xx:指示服务器端错误–服务器未能实现合法的请求。
# 缓存分类
# 按协议分
协议层缓存和非 http 协议缓存
非协议层缓存:利用 meta
标签的 http-equiv
属性值 Expires
,set-cookie
。
协议层缓存:利用 http 协议头属性值设置;
# 按缓存分
强缓存和协商缓存
强缓存:利用 cache-control 和 expires 设置,直接返回一个过期时间,所以在缓存期间不请求,If-modify-since; 协商缓存:响应头返回 etag 或 last-modified 的哈希值,第二次请求头 If-none-match 或 IF-modify-since 携带上次哈希值,一致则返回 304。
类型 | 特性 |
---|---|
强缓存 | 通过 If-modify-since(last-modify)、expires 和 cache-control 设置,属性值是时间,所以在时间内不用请求 |
协商缓存 | 通过 If-none-match(etag)设置,etag 属性是哈希值,所以要请求和服务器值对比 |
# 缓存比较
强制缓存的优先级高于协商缓存,当执行强制缓存时,如若缓存命中,则直接使用缓存数据库数据,不在进行缓存协商。
协商缓存对比: etag 优先级高于 last-modified; etag 精度高,last-modified 精度是 s,1s 内 etag 修改多少次都会被记录; last-modified 性能好,etag 要得到 hash 值。
如果不是强制刷新,而且请求头带上了if-modified-since和if-none-match两个字段,则先判断etag,再判断last-modified。
# 校验过期机制
- 校验是否过期: Expires, Cache-Control(max-age)
- 协议Etag头信息校验; Etag
- 协议中Last-Modified头信息校验;Last-Modified
# 各协议比较及细分
# 协议群
# 体系结构与协议群
# 通信过程
# 相关
# OSI七层模型和TCP/IP四层模型
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
TCP/IP 四层概念:
- 应用层:应用层、表示层、会话层:HTTP
- 传输层:传输层:TCP/UDP
- 网络层:网络层:IP
- 数据链路层:数据链路层、物理层
# TCP/UDP
# TCP/UDP协议的区别【要点】
# 比较
TCP有粘包的情况;
协议 | 连接性 | 双工性 | 可靠性 | 有序性 | 有界性 | 拥塞控制 | 传输速度 | 量级 | 头部大小 |
---|---|---|---|---|---|---|---|---|---|
TCP | 面向连接(Connection oriented) | 全双(1:1) | 可靠(重传机制) | 有序(通过SYN排序) | 无, 有粘包情况 | 有 | 慢 | 低 | 20~60字节 |
UDP | 无连接(Connection less) | n:m | 不可靠(丢包后数据丢失) | 无序 | 有消息边界, 无粘包 | 无 | 快 | 高 | 8字节 |
# TCP 协议怎么保证可靠的,UDP 为什么不可靠?
- TCP 是面向连接的、可靠的、传输层通信协议
- UDP 是无连接的传输层通信协议,继承 IP 特性,基于数据报
为什么 TCP 可靠?TCP 的可靠性体现在有状态和控制
- 会精准记录那些数据发送了,那些数据被对方接收了,那些没有被接收,而且保证数据包按序到达,不允许半点差错,这就是有状态
- 当意识到丢包了或者网络环境不佳,TCP 会根据具体情况调整自己的行为,控制自己的发送速度或者重发,这是可控制的
反之 UDP 就是无状态的和不可控制的
# TCP粘包/拆包
详细可见【Websocket的使用】中的详细介绍;
当一次发送数据过长时,tcp 会把数据封成多个包发送;同样当数据过短时, 会把数据合并成一个包发送,这种现象就是粘包。
默认情况下, TCP 连接会启用延迟传送算法
(Nagle 算法), 在数据发送之前缓存他们. 如果短时间有多个数据发送, 会缓冲到一起作一次发送 (缓冲大小见 socket.bufferSize
), 这样可以减少 IO 消耗提高性能.如果是传输文件的话, 那么根本不用处理粘包的问题, 来一个包拼一个包就好了. 但是如果是多条消息, 或者是别的用途的数据那么久需要处理粘包.
可以参见网上流传比较广的一个例子:
连续调用两次 send 分别发送两段数据 data1 和 data2, 在接收端有以下几种常见的情况:
- A. 先接收到 data1, 然后接收到 data2 .
- B. 先接收到 data1 的部分数据, 然后接收到 data1 余下的部分以及 data2 的全部.
- C. 先接收到了 data1 的全部数据和 data2 的部分数据, 然后接收到了 data2 的余下的数据.
- D. 一次性接收到了 data1 和 data2 的全部数据.
其中的 BCD 就是我们常见的粘包的情况. 而对于处理粘包的问题, 常见的解决方案有:
- 多次发送之前间隔一个等待时间;
- 关闭 Nagle 算法;
- 进行封包/拆包;封包/拆包是目前业内常见的解决方案了. 即
给每个数据包在发送之前, 于其前/后放一些有特征的数据, 然后收到数据的时候根据特征数据分割出来各个数据包
.
# 对 TCP 滑动窗口有了解嘛?
TCP 滑动窗口分为两种: 发送窗口和接收窗口。
在 TCP 链接中,对于发送端和接收端而言,TCP 需要把发送的数据放到发送缓存区, 将接收的数据放到接收缓存区。而经常会存在发送端发送过多,而接收端无法消化的情况,所以就需要流量控制,就是在通过接收缓存区的大小,控制发送端的发送。如果对方的接收缓存区满了,就不能再继续发送了。而这种流量控制的过程就需要在发送端维护一个发送窗口,在接收端维持一个接收窗口。
# TCP三次握手/四次挥手
# TCP 三次握手的过程
- 客户端发送一个带 SYN=1,Seq=X 的数据包到服务器端口(第一次握手,由浏览器发起,告诉服务器我要发送请求了)
- 服务器发回一个带 SYN=1, ACK=X+1, Seq=Y 的响应包以示传达确认信息(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)
- 客户端再回传一个带 ACK=Y+1, Seq=Z 的数据包,代表“握手结束”(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)
# TCP 四次握手的过程
- 发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)
- 被动方发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入 FIN_WAIT_2 状态。(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)
- 被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)
- 发起方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)
# 图示
# 通俗图示
# 相关
# 为什么建立连接协议是三次握手,而关闭连接却是四次挥手呢?
普通原理:
- 防止服务器端因接收了早已失效的连接请求报文,从而一直等待客户端请求,最终导致形成死锁、浪费资源;【三次握手】
- 为了保证通信双方都能通知对方 需释放 & 断开连接【四次挥手】
内部原理:
三次握手:这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。
四次挥手:当关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET, 也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
# 连接为什么不是两次?
无法确认客户端的接收能力。如果首先客户端发送了 SYN 报文,但是滞留在网络中,TCP 以为丢包了,然后重传,两次握手建立了连接。
等到客户端关闭连接了。但是之后这个包如果到达了服务端,那么服务端接收到了,然后发送相应的数据表,就建立了链接,但是此时客户端已经关闭连接了,所以带来了链接资源的浪费。
# 连接为什么不是四次?
四次以上都可以,只不过 三次就够了;
# 断开为什么需要等待 2MSL(Maximum Segement Lifetime):
因为如果不等待的话,如果服务端还有很多数据包要给客户端发,且此时客户端端口被新应用占据,那么就会接收到无用的数据包,造成数据包混乱,所以说最保险的方法就是等服务器发来的数据包都死翘翘了再启动新应用;
- 1个 MSL 保证四次挥手中主动关闭方最后的 ACK 报文能最终到达对端
- 1个 MSL 保证对端没有收到 ACK 那么进行重传的 FIN 报文能够到达
# 断开为什么是四次而不是三次?
如果是三次的话,那么服务端的 ACK 和 FIN 合成一个挥手,那么长时间的延迟可能让 TCP 一位 FIN 没有达到服务器端,然后让客户的不断的重发 FIN;
# TCP 如何保证有效传输及拥塞控制原理。
- tcp 是面向连接的、可靠的、传输层通信协议
可靠体现在:有状态、可控制
- 有状态是指 TCP 会确认发送了哪些报文,接收方受到了哪些报文,哪些没有收到,保证数据包按序到达,不允许有差错
- 可控制的是指,如果出现丢包或者网络状况不佳,则会跳转自己的行为,减少发送的速度或者重发
所以上面能保证数据包的有效传输。
拥塞控制原理
原因是有可能整个网络环境特别差,容易丢包,那么发送端就应该注意了。
主要用三种方法:
- 慢启动阈值 + 拥塞避免
- 快速重传
- 快速回复
慢启动阈值 + 拥塞避免
对于拥塞控制来说,TCP 主要维护两个核心状态:
- 拥塞窗口(cwnd)
- 慢启动阈值(ssthresh)
在发送端使用拥塞窗口来控制发送窗口的大小。
然后采用一种比较保守的慢启动算法来慢慢适应这个网络,在开始传输的一段时间,发送端和接收端会首先通过三次握手建立连接,确定各自接收窗口大小,然后初始化双方的拥塞窗口,接着每经过一轮 RTT(收发时延),拥塞窗口大小翻倍,直到达到慢启动阈值。
然后开始进行拥塞避免,拥塞避免具体的做法就是之前每一轮 RTT,拥塞窗口翻倍,现在每一轮就加一个。
快速重传
在 TCP 传输过程中,如果发生了丢包,接收端就会发送之前重复 ACK,比如 第 5 个包丢了,6、7 达到,然后接收端会为 5,6,7 都发送第四个包的 ACK,这个时候发送端受到了 3 个重复的 ACK,意识到丢包了,就会马上进行重传,而不用等到 RTO (超时重传的时间)
选择性重传:报文首部可选性中加入 SACK 属性,通过 left edge 和 right edge 标志那些包到了,然后重传没到的包
快速恢复
如果发送端收到了 3 个重复的 ACK,发现了丢包,觉得现在的网络状况已经进入拥塞状态了,那么就会进入快速恢复阶段:
- 会将拥塞阈值降低为 拥塞窗口的一半
- 然后拥塞窗口大小变为拥塞阈值
- 接着 拥塞窗口再进行线性增加,以适应网络状况
# http/https
# http版本的比较
版本 | 内容 |
---|---|
http0.9 | 只允许客户端发送 GET 这一种请求;且不支持请求头,协议只支持纯文本;无状态性,每个访问独立处理,完成断开;无状态码 |
http1.0 | 解决 0.9 的缺点,增加 If-modify-since(last-modify)和 expires 缓存属性 |
http1.x | 增加 cache-control 和 If-none-match(etag)缓存,keep-alive 属性 |
http2.0 | 采用二进制格式传输;多路复用;报头压缩;服务器推送 |
http3.0 | 采用 QUIC 协议,自定义连接机制;自定义重传机制;无阻塞的多路复用 |
# HTTP 2 改进
改进性能:
- 头部压缩
- 多路信道复用
- Server Push
# HTTP状态码
# 比较分类
序列 | 详情 |
---|---|
1XX(通知) | 代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。101 Switching Protocols |
2XX(成功) | 200(成功)、201(服务器创建)、202(服务器接收未处理)、203(非授权信息)、204(未返回内容)、205(重置内容)、206(部分内容) |
3XX(重定向) | 301(永久移动)、302(临时移动)、303(查看其他位置)、304(未修改)、305(使用代理)、307(临时重定向) |
4XX(客户端错误) | 400(错误请求)、401(未授权)、403(禁止)、404(未找到)、405(方法禁用)、406(不接受)、407(需要代理授权) |
5XX(服务器错误) | 500(服务器异常)、501(尚未实施)、502(错误网关)、503(服务不可用)、504(网关超时)、505(HTTP 版本不受支持) |
总括:
- 1xx:指示信息–表示请求已接收,继续处理。
- 2xx:指示成功–表示请求已被成功接收、理解、接受。
- 3xx:指示重定向–要完成请求必须进行更进一步的操作。
- 4xx:指示客户端错误–请求有语法错误或请求无法实现。
- 5xx:指示服务器端错误–服务器未能实现合法的请求。
# 特殊状态码
- 301: 请求的资源被永久转移到其他地方(重定向);
- 302: 临时转移;
- 501/505(koa中有处理)
- 206: range范围请求; range范围请求【206】;显示一个请求文件的多少行
模拟:
curl -r 0-10 http://127.0.0.1:9527/LICENSE (10行)
- 304: 缓存(新鲜度) Request Headers跟 Response Headers 中的 Last-Modified/ETag一样,才确保是新鲜的304;
# http 状态码中 301,302和307有什么区别
301,Moved Permanently。永久重定向,该操作比较危险,需要谨慎操作:如果设置了301,但是一段时间后又想取消,但是浏览器中已经有了缓存,还是会重定向。
302,Fount。临时重定向,但是会在重定向的时候改变 method: 把 POST 改成 GET,于是有了 307
307,Temporary Redirect。临时重定向,在重定向时不会改变 method
# http 向 https 做重定向应该使用哪个状态码
一般用作 301
的较为多,但是也有使用 302
,如果开启了 HSTS
则会使用 307
如知乎使用了 302,淘宝使用了 301
$ curl --head www.zhihu.com
HTTP/1.1 302 Found
Date: Tue, 24 Dec 2019 00:13:54 GMT
Content-Length: 22
Connection: keep-alive
Server: NWS_TCloud_IPV6
Location: https://www.zhihu.com/
X-NWS-LOG-UUID: 0e28d9a1-6aeb-42cd-9f6b-00bd6cf11500
$ curl --head www.taobao.com
HTTP/1.1 301 Moved Permanently
Server: Tengine
Date: Tue, 24 Dec 2019 00:13:58 GMT
Content-Type: text/html
Content-Length: 278
Connection: keep-alive
Location: https://www.taobao.com/
Via: cache20.cn1480[,0]
Timing-Allow-Origin: *
EagleId: 6f3f38a815771464380412555e
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# http 状态码 502 和 504 有什么区别
502 Bad Gateway The server was acting as a gateway or proxy and received an invalid response from the upstream server. 收到了上游响应但无法解析
504 Gateway Timeout The server was acting as a gateway or proxy and did not receive a timely response from the upstream server. 上游响应超时
# 既然 http 是无状态协议,那它是如何保持登录状态
通过 cookie 或者 Authorization header 来传递凭证,在服务端进行认证
# 如何从 http 的报文中得知该服务使用的技术栈
一般有两个 response header,有时服务端为了隐蔽自己真实的技术栈会隐蔽这两个字段
X-Powerd-By
Server
可在nginx中关闭屏蔽这几个字段;
# 在交互过程中如果数据传送完了,还不想断开连接怎么办,怎么维持?
在 HTTP 中响应体的 Connection 字段指定为 keep-alive
# 几种请求方法【要点】
GET、POST、PUT、DELETE、HEAD、CONNECT、OPTIONS、TRACE;
常用的6种【CRUD操作+ H+P】
methods | CRUD | 幂等 | 缓存 |
---|---|---|---|
GET | Read | ✓ | ✓ |
POST | Create | ||
PUT | Update/Replace | ✓ | |
PATCH | Update/Modify | ||
DELETE | Delete | ✓ |
http/1.1 规定如下请求方法:
- GET:通用获取数据
- HEAD:获取资源的元信息
- POST:提交数据
- PUT:修改数据
- DELETE:删除数据
- CONNECT:建立连接隧道,用于代理服务器
- OPTIONS:列出可对资源实行的请求方法,常用于跨域
- TRACE:追踪请求-响应的传输路径
# POST 和 PUT 的区别
POST 是新建 (create) 资源, 非幂等, 同一个请求如果重复 POST 会新建多个资源. PUT 是 Update/Replace, 幂等, 同一个 PUT 请求重复操作会得到同样的结果.
# get和post区别
请求方式 | GET | POST |
---|---|---|
参数位置 | 参数拼接到url的后面 | 参数在请求体中 |
参数大小 | 受限于浏览器url大小,一般不超过32K | 1G |
服务器数据接收 | 接收1次 | 根据数据大小,可分多次接收 |
适用场景 | 从服务器端获取数据 | 向服务器提交数据 |
安全性 | 参数携带在url中,安全性低 | 相对于GET请求,安全性更高 |
# POST一般可以发送什么类型的文件,数据处理的问题
- 文本、图片、视频、音频等都可以
- text/image/audio/ 或 application/json 等
# OPTION是干啥的?举个用到OPTION的例子?
旨在发送一种探测请求,以确定针对某个目标地址的请求必须具有怎么样的约束,然后根据约束发送真正的请求。
比如针对跨域资源的预检,就是采用 HTTP 的 OPTIONS 方法先发送的。用来处理跨域请求
# 请求响应头
常用请求头:1.请求和响应报文的通用Header;2.常用的响应Header;
# 从URL输入到页面展现内部过程(8步)【要点】
# 图示流程
# 总体流程(8步)
总体流程:(八部曲):谐音 【输缓域三,请响解四】
- 浏览器的地址栏输入URL并按下回车
- 浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
- DNS 解析: 将域名解析成 IP 地址
- 根据IP建立TCP连接(三次握手)。
- 发送 HTTP 请求
- 服务器处理请求,浏览器接收HTTP响应。
- 浏览器解析渲染页面
- 断开TCP连接:TCP 四次挥手
总体流程:(八部曲):谐音 【输缓域三,请响解四】
- 浏览器的地址栏输入URL并按下回车;
- 浏览器查找当前URL是否存在缓存,并比较缓存是否过期;
- DNS 解析: 将域名解析成 IP 地址;
- 根据IP建立TCP连接(三次握手);
- 发送 HTTP 请求;
- 服务器处理请求,浏览器接收HTTP响应;
- 浏览器解析渲染页面;
- 断开TCP连接:TCP 四次挥手;
详细步骤:
TCP 三次握手结束后,开始发送 HTTP 请求报文。 请求报文由请求行(request line)、请求头(header)、请求体
1.请求行包含请求方法、URL、协议版本
2.请求头包含请求的附加信息,由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。 比如:Host,表示主机名,虚拟主机;Connection,HTTP/1.1 增加的,使用 keepalive,即持久连接,一个连接可以发多个请求;User-Agent,请求发出者,兼容性以及定制化需求。
3.请求体,可以承载多个请求参数的数据,包含回车符、换行符和请求数据,并不是所有请求都具有请求数据
首先浏览器发送过来的请求先经过控制器,控制器进行逻辑处理和请求分发,接着会调用模型,这一阶段模型会获取 redis db 以及 MySQL 的数据,获取数据后将渲染好的页面,响应信息会以响应报文的形式返回给客户端,
最后浏览器通过渲染引擎将网页呈现在用户面前。
- 根据 HTML 解析出 DOM 树
- 根据 CSS 解析生成 CSS 规则树
- 结合 DOM 树和 CSS 规则树,生成渲染树
- 根据渲染树计算每一个节点的信息
- 根据计算好的信息绘制页面
当数据传送完毕,需要断开 tcp 连接,此时发起 tcp 四次挥手。
# 长连接
# HTTP 如何实现长连接?在什么时候会超时?
通过在头部(请求和响应头)设置 Connection: keep-alive,HTTP1.0协议支持,但是默认关闭,从HTTP1.1协议以后,连接默认都是长连接
- HTTP 一般会有 httpd 守护进程,里面可以设置 keep-alive timeout,当 tcp 链接闲置超过这个时间就会关闭,也可以在 HTTP 的 header 里面设置超时时间
- TCP 的 keep-alive 包含三个参数,支持在系统内核的 net.ipv4 里面设置:当 TCP 链接之后,闲置了 tcp_keepalive_time,则会发生侦测包,如果没有收到对方的 ACK,那么会每隔 tcp_keepalive_intvl 再发一次,直到发送了 tcp_keepalive_probes,就会丢弃该链接。
- tcp_keepalive_intvl = 15
- tcp_keepalive_probes = 5
- tcp_keepalive_time = 1800
实际上 HTTP 没有长短链接,只有 TCP 有,TCP 长连接可以复用一个 TCP 链接来发起多次 HTTP 请求,这样可以减少资源消耗,比如一次请求 HTML,可能还需要请求后续的 JS/CSS/图片等
# 相关
# http知道嘛?哪一层的协议?(应用层)
- 灵活可扩展,除了规定空格分隔单词,换行分隔字段以外,其他都没有限制,不仅仅可以传输文本,还可以传输图片、视频等任意资源
- 可靠传输,基于 TCP/IP 所以继承了这一特性
- 请求-应答,有来有回
- 无状态,每次 HTTP 请求都是独立的,无关的、默认不需要保存上下文信息
缺点:
- 明文传输不安全
- 复用一个 TCP 链接,会发生对头拥塞
- 无状态在长连接场景中,需要保存大量上下文,以避免传输大量重复的信息
# 缓存
# 按协议分
协议层缓存和非 http 协议缓存
非协议层缓存:利用 meta
标签的 http-equiv
属性值 Expires
,set-cookie
。
协议层缓存:利用 http 协议头属性值设置;
# 按缓存分
强缓存和协商缓存
强缓存:利用 cache-control 和 expires 设置,直接返回一个过期时间,所以在缓存期间不请求,If-modify-since; 协商缓存:响应头返回 etag 或 last-modified 的哈希值,第二次请求头 If-none-match 或 IF-modify-since 携带上次哈希值,一致则返回 304。
类型 | 特性 |
---|---|
强缓存 | 通过 If-modify-since(last-modify)、expires 和 cache-control 设置,属性值是时间,所以在时间内不用请求 |
协商缓存 | 通过 If-none-match(etag)设置,etag 属性是哈希值,所以要请求和服务器值对比 |
# 缓存比较
强制缓存的优先级高于协商缓存,当执行强制缓存时,如若缓存命中,则直接使用缓存数据库数据,不在进行缓存协商。
协商缓存对比: etag 优先级高于 last-modified; etag 精度高,last-modified 精度是 s,1s 内 etag 修改多少次都会被记录; last-modified 性能好,etag 要得到 hash 值。
如果不是强制刷新,而且请求头带上了if-modified-since和if-none-match两个字段,则先判断etag,再判断last-modified。
# 校验过期机制
- 校验是否过期: Expires, Cache-Control(max-age)
- 协议Etag头信息校验; Etag
- 协议中Last-Modified头信息校验;Last-Modified
# 缓存的优点
- 减少了冗余的数据传递,节省宽带流量
- 减少了服务器的负担,大大提高了网站性能
- 加快了客户端加载网页的速度 这也正是HTTP缓存属于客户端缓存的原因。
# 浏览器读取缓存流程
F5 刷新会忽略强缓存不会忽略协商缓存,ctrl+f5 都失效
1:会先判断强缓存,Expires, Cache-Control(max-age) no-cache=true, public ;
2:再判断协商缓存 etag
及last-modified
是否存在;
3:存在利用属性 If-None-match(etag)If-Modified-since(last-modified)携带值(这一步叫做数据签名);
4:请求服务器,服务器对比 etag(last-modified),生效返回 304。
缓存的优先级:cache-control > expires > Etag > last-modified
图示流程:
代码处理示例:
# 不同刷新的请求执行过程
浏览器地址栏中写入URL,回车 浏览器发现缓存中有这个文件了,不用继续请求了,直接去缓存拿.(最快)
F5 F5就是告诉浏览器,别偷懒,好歹去服务器看看这个文件是否有过期了。于是浏览器就胆胆襟襟的发送一个请求带上If-Modify-since。
Ctrl+F5 告诉浏览器,你先把你缓存中的这个文件给我删了,然后再去服务器请求个完整的资源文件下来。于是客户端就完成了强行更新的操作.
# 200 From cache和200 OK有什么区别
- 顾名思义是form cache是强缓存,不会和服务器通信,
- 而200 OK即为服务器处理结果正确。以此可以从浏览器缓存、输入url回车、刷新页面以及强制刷新等方面展开缓存方面的讲解。
# 能不能说下 304 的过程,以及影响缓存的头部属性有哪些?
写那个缓存流程图即可; 1、对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。 2、对于比较缓存,将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。
# websocket
长轮询和短轮询,WebSocket 是长轮询。
具体比如在一个电商场景,商品的库存可能会变化,所以需要及时反映给用户,所以客户端会不停的发请求,然后服务器端会不停的去查变化,不管变不变,都返回,这个是短轮询。
而长轮询则表现为如果没有变,就不返回,而是等待变或者超时(一般是十几秒)才返回,如果没有返回,客户端也不需要一直发请求,所以减少了双方的压力。
# WebSocket与Ajax的区别
本质不同:
Ajax 即异步 JavaScript 和 XML,是一种创建交互式网页的应用的网页开发技术
websocket 是 HTML5 的一种新协议,实现了浏览器和服务器的实时通信
生命周期不同:
- websocket 是长连接,会话一直保持
- ajax 发送接收之后就会断开
适用范围:
- websocket 用于前后端实时交互数据
- ajax 非实时
发起人:
- AJAX 客户端发起
- WebSocket 服务器端和客户端相互推送
# 网络请求
# Fetch API与传统Request的区别
- fetch 符合关注点分离,使用 Promise,API 更加丰富,支持 Async/Await
- 语意简单,更加语意化
- 可以使用 isomorphic-fetch ,同构方便