一、强缓存和协商缓存
强缓存
本地缓存,浏览器不会发请求,直接从本地缓存中读取。
控制强缓存的字段:expires和 cache-control
expires:记录的是一个绝对时间的字符串,为过期时间,在这个事件之前,就不需要请求服务器去拿。
cache-control:max-age=number,相对时间,相对时间内,缓存是有效的。
Cache-Control与Expires可以在服务端配置同时启用,同时启用的时候Cache-Control优先级高
协商缓存
协商缓存是需要在服务端对比资源是否已经修改了,来判断是否可以使用缓存。若未改动,返回304状态码。
控制协商缓存的两个header字段是:Last-Modify/If-Modified-Since 和 Etag/If-None-Match,这两个字段是成对使用的。
Last-Modify/If-Modified-Since
浏览器第一次请求服务器的时候,响应头会返回Last-modify字段,记录资源的最后修改时间。
浏览器再次请求服务器,请求头携带If-Modified-Since,值为缓存之前的时间,根据资源最后的修改时间判断是否缓存命中。若没有修改,返回304,使用缓存。若修改,再去服务器请求资源,返回码和第一次请求时的返回码一样为200。
Etag/If-None-Match
Etag是服务器根据资源的内容生成的hash字符串,记录资源的状态,资源只要变换,Etag也会变,然后Etag的值下次会存在请求的If-None-Match字段中。
协商缓存与强制缓存的区别在于强制缓存不需要访问服务器,返回结果是200,协商缓存需要访问服务器,如果命中缓存的话,返回结果是304。
Etag相对于last-modified的优势,
- 对于某些周期性会修改的文件,可能内容未修改,但是时间修改了,我们不希望任何这个文件被修改过。
- 某些文件的修改十分频繁,1s修改了好多次,If-Modified-since不能精确地匹配最后的修改时间。
缓存机制
浏览器发送请求,会先根据响应头的Cache-control和expires判断是否可用,如果没过期,就直接从浏览器缓存获取资源。如果强缓存不可用,就会使用协商缓存。
浏览器把之前保存的last-modified和etag存在请求头发给服务器,服务器会自己对照之前的和现在的,若命中,则返回304空响应,否则会返回新的资源和etag以及状态码OK。
二、TCP协议的三次握手和四次握手
TCP协议位于传输层,为了提供可靠的字节流服务。为了传输方便,把大块数据分割为数据包进行管理,且TCP协议能够确认数据最终是否到达对方,且在传输时是有序的。
1. 建立连接:三次握手,使用了TCP的标志 SYN(synchronize)和 ACK(acknowledgement)
第一次,建立连接时,客户端A发送SYN包(SYN=j)到服务器B,服务器B收到后知道客户端希望建立连接。
第二次,服务器B收到SYN包,确认是A的SYN,发ACK=j+1,同时自己也发SYN=k。
第三次,客户端需要发送ACK=k+1确认,说知道了你要和我建立连接,否则,服务端不知道自己发的消息客户端能不能收到。
两方都知道 自己能发送消息,也可以接受消息
第三次握手防止已经失效的TCP请求突然又到达服务端,服务端误以为有新的TCP请求,会一直等待,浪费资源
2. 断开连接:四次挥手,使用了FIN标志,当发了FIN标志后,这个方向终止连接,但是收到FIN的仍然可以发数据。另外,先执行关闭的一方将执行主动关闭,否则是被动关闭。
第一次,客户端A发一个FIN=l,关闭与服务端B的数据传输。
第二次,服务端收到FIN=l,返回一个ACK=l+1,代表知道客户端A关闭数据传输了。(客户端已经准备取消连接了,但是服务端还没有)
第三次,服务端B关闭与客户端A的连接,发送一个FIN=k给客户端A。
第四次,客户端A发ACK=k+1确认。
三、http1.0,http1.1和http2的区别
1.0和1.1的区别
1.长连接
http1.0默认为短链接。需要手动设置成长连接,而http1.1默认设置为keep-alive。当客户端和服务器每进行一次HTTP操作,就要建立连接,任务结束中断了链接。要知道创建一个TCP连接要经过3次握手,开销十分的大,对传输性能也有影响,维持一个长连接十分重要,可以发多个请求。
关键代码:Connection:keep-alive;
2.缓存策略
http1.00主要依赖强缓存的Expires和协商缓存Last-Modify作为缓存标准,而http1.1引入了更多缓存控制策略入Cache-Control和Etags.
3.Host头处理
http1.0的请求中不会传递host主机名,但是现在一台物理服务器可以有多个虚拟主机共享ip,所以HTTP1.1的请求和响应都支持Host,如果请求错误会报400 Bad Request。
4.节约带宽
http1.1在请求头中引入range头域,允许请求资源的一部分,返回206(partial content),方便开发者充分利用带宽。
1.1和2.0的区别
1. 多路复用
http2.0支持多路复用技术,同一个连接可以并发实现多个请求,并发请求的数量级比HTTP1.1要大很多
如何实现多路复用的?
我们知道TCP的传输是靠字节码传输,每个字节都是一个一个传输,理论下是不可能并发请求的。所以在并发请求时,给所有传输的包打上标签,到了服务器,服务器根据标签再在把数据包结合起来,就可以实现并发请求。
2. 首部压缩
对于Http1,Http的报文都是 行、头和体,一般体会被gzip压缩,但是行和头不会压缩。
HTTP 2.0 使用HPACK算法对header的数据进行压缩,数据体积减少,减少了数据包的数量,降低延迟。
HPACK算法主要是维护一份静态字典和动态字典。
静态字典里包换常见的头的key和常见的key和value,以字符表示。
例如不会平凡变动的key,Cookie和UserAgent,我就用字符代替写入请求和响应代替,就大大减少传输数据量。
3. 服务器推送(server push)
解释:在服务端请求资源之前推送数据。及服务器可以根据一个请求发多个响应,充分利用网络空间,减小加载时间,
为什么:一个网页有html、样式表、脚本、图片、video等等。假如HTTP1.X中一个一个的请求资源,速度慢,且服务器必须等待一个一个的请求,然后在发送,网络经常是空闲的。
4. 二进制分帧层
在应用层和传输层间增加一个二进制分帧层,会把Http1.x的header和body封装成HEADERS frame 和DATA frame,改进传输性能,实现低延迟和高吞吐量。
四、HTTPs为什么安全
HTTPs=HTTP+SSL(Secure Socket Layer)。
HTTP上建立SSL加密层,对数据传输加密。
HTTP不安全的原因:
- HTTP传输是明文传输,报文都可见,内容可能被窃听。
2.无法验证报文的完整性,有可能在请求或响应发出后,请求和响应被删改,但是没法获悉。
3.HTTP协议是无状态的,服务端不知道通信方究竟是不是之前的客户端,即请求和响应不会对通信方确认 。所以也会有CSRF。
所以针对以上:
- 加密内容保隐私:对称加密+非对称加密
- 数字签名:防内容篡改
- SSL证书:验证身份,防伪装
首先,HTTP需要先和SSL通信,然后SSL再和TCP通信。
对称加密+非对称加密:
对称加密解密速度快,而非对称加密是传输内容不易破解。所以,HTTPS采用如下做法:
发密文的一方使用对方的公钥进行对“对称密钥”的加密,然后接收方用自己的私钥解密“对称密钥”,这样就可以确保较换密钥的安全。
数字签名:
SSL证书:
流程:
1.客户端发起一个HTTPs请求,这个请求默认443端口。
2.服务端把公钥证书返回客户端。
3.客户端验证证书,若无效则显示警告,若有效则继续。
4.客户端用随机数生成器生成所需要的“对称密钥”,然后用证书的公钥加密“对称密钥”,发给服务端
5.服务端用自己的私钥解密,得到了对称密钥。于是服务端和客户端都有了相同的对称密钥。
- 服务端开始发送以对称密钥加密的明文响应给客户端。
- 客户端解密,得明文响应。
8.客户端发请求,会使用密钥加密的内容。服务端再用密钥解密。
五、断点续传
断点续传就是从文件上次中断的地方重新下载或者上传。如果没有断点续传的功能,每次传输出现异常或者用户暂停传输,都会去重头下载,浪费时间。HTTP1.1开始支持断电续传。
一般用到Range和Content-Range字段头。用于获取服务器中大文件的一部分内容。(指定开始-结束)
- 客户端下1024K文件,已下载了512k
2.网络中断,客户端请求续传,在请求头写:Range:bytes=512000-
3.服务器收到断点续传,从512开始传输,并在响应头里写Content-Range:bytes:512000-/102400
此时状态码为206(partial content)
当然有时候在续传时,url对应的文件在服务端已经更新了,就需要从新下载,所以在续传时,请求头要有If-modified-since和If-none-match的标注,检验是否改动,若改动,则返回新的文件的全部数据(200),否则206。
六、堆、栈、队列
堆(heap)
堆(heap)是指程序运行时申请的动态内存,在JS运行时用来存放对象。
栈(stack)
栈(stack)遵循的原则是“先进后出”,JS种的基本数据类型与指向对象的地址存放在栈内存中,此外还有一块栈内存用来执行JS主线程–执行栈(execution context stack)
队列(queue)
队列(queue)遵循的原则是“先进先出”,JS中除了主线程之外还存在两个“任务队列”(微任务队列microTask和宏任务队列macroTask)。
微任务:promise.then
宏任务:setTimeout, setInterval