OSI七层模型
应用层:负责用户交互、应用操作, 包含Https、Http、DNS、FTP、SMTP等。
表示层:把网络中的消息转换成应用层可以读取消息格式。
会话层:完全概念层,负责建立会话,传输数据每次建立HTTP会话。
传输层:保证了进程到进程之间的通信,如TCP,UDP协议,包含流量控制、报文可达性。
网络层:在同一个局域网中,确保可以将报文从另一个主机传输到另一个主机上。
数据链路层:使用MAC地址连接到对应的交换机(路由器)
物理层:转发报文需要的一些介质
TCP/IP协议模型
TCP/IP协议(传输控制协议)是指能够在多个不同网络间实现信息传输的协议簇,包含了TCP、IP、FTP、UDP、SMTP等协议构成的协议簇。
四层体系结构:
应用层:应用程序沟通层,包含HTTP协议、文件传输FTP协议、简单电子邮件SMTP传输协议
传输层:提供应用程序之间的通信服务,主要功能是数据格式化、数据确认和丢失重传等。如传输控制协议TCP、用户数据报协议UDP等。
网络层:负责提供基本的数据封包传输功能,让每个数据包能够到达目的主机
数据链路层:接受IP数据包并进行传输,从网络上接收物理帧,抽取IP数据包转交给下一层,对实际的网络媒体管理。
五层网络协议体系结构
结合OSI模型和TCP/IP模型
应用层:协议体系中的最高层,为用户应用程序提供通信服务。比如HTTP、FTP、DNS等
传输层:负责两个主机的进程之间的通信服务,因为一个主机有不同的进程,所以运输层有分用和复用功能。
分用:运输层将收到的消息分别交付给应用层相应的程序。 复用:多个应用程序可以同时使用下面运输层的服务。
网络层:将运输层的报文分组(IP数据报),为同一局域网中的不同主机提供通信服务。
数据链路层:将网络层传输的数据报封装成帧,在相邻两个节点间的链路间透明的传输帧数据。
物理层:该层传输数据的单位是比特。
HTTP的报文结构
起始行 头部 空行 实体
起始行:请求行 GET /home HTTP/1.1 响应行(状态行) HTTP/1.1 200 OK
头部:主要是比较多的头部字段。
头部字段格式
-
字段名不区分大小写
-
字段名不允许出现空格,不可以出现下划线_
-
字段名后面必须紧跟
:
空行:区分开头和实体
实体:具体数据body部分
Content-type取值
Content-type用来向接收方指名实体的介质类型。可以出现在响应/请求报文头部
application/x-www-form-urlencoded: 将参数分解成 & 拼接成的key-value形式
multipart/form-data: 由form表单的enctype指明,它会将表达数据处理位为一条信息,以标签为单元,用分隔符(-bounary-)隔开
application/json : 告诉服务器是序列化后的JSON字符串
binary(application/octet-stream): 一般用于提交二进制文件
头部字段
通用头部:
Content-Length: 范文请求种指明文件长度,(request和respond)
Request Header
Referer: 本页面的上一个点击跳转页
Origin: 当前请求站名信息
User_Agent : 请求的浏览器版本信息等
Accept: 客户端支持接受的文本格式类型,与服务端返回的文本格式类型Content-Type对应
Accpet-encoding: 表示客户端支持的压缩算法
Accept-language: 表示客户端接受的语言
Response Header
Server: 表示服务器信息
Content-Type :服务端返回的内容类型
Content-encoding: 返回文件的压缩类型
Content-Language:返回语言类型
缓存:
Request Header
If-None-Match: 客户端提供的上一次请求返回的ETag信息
If-Since-Modified:客户端提供的上一次请求返回的Last-Modified信息
Response Header
Cache-Control:no-store,no-cache,public,表示是否使用浏览器缓存,max-age: 资源在本地的最大存活时间;
Expires:格林尼治时间,表示资源过期的时间点,本地时间可以修改以至资源过期
ETag : 表示服务端资源标识,可以精确到ms
Last-Modified: 表示服务端最后一次修改时间,可以精确到s
范围请求- 大文件信息
Request Header
Accept-Range:bytes: 客户端接受的请求范围
Content-Length: 请求的完整大小
Range:bytes=10-20请求范围,单位字节
Response Header
Content-Range:bytes 0-50/1270 响应回来的内容长度
Content-Length:50 完整的响应大小
Cookie相关的
Request Header
Cookie: 多个key-value形式的键值对组成
Respond Header
Set_Cookie: 一个key-value键值对,一个响应投可以有多个Set-Cookie
CORS实现跨域请求
Request Header
Origin: 客户端当前的发送请求的域名
Respond Header
Access-Control-Allow-Origin: 服务端支持CORS跨域请求的域名
Access-Control-Allow-Credentials:true: 服务端请求携带Cookie
Access-Control-Allow-Method: 服务端允许跨域请求的方法
Access-Control-Allow-Headers:Content-Type:允许跨域请求设置请求头
HTTP/1.0
特点:
-
短链接(无状态),即发送一次请求建立一条TCP连接,请求处理完之后立即断开连接,不复用请求上下文信息。 -
队头阻塞:发送消息是一发一收形式,也就是发送请求报文时必须等到上一个请求报文发送并得到服务端响应之后才能发送下一个报文,如果上一个报文迟迟没有得到响应,就会阻塞请求队列中的报文发送。
HTTP/1.1
长连接,增加了响应头部connection:keep-alive;表示一条TCP连接可以复用,发送多个HTTP请求。
管线化传输(流水线传输),也就是为了解决HTTP/1.0中对头阻塞问题,让发送端可以连续发送多条请求报文,试图解决阻塞问题。但是在服务端依旧需要顺序接受请求报文并返回响应,所以实际上阻塞问题只是从客户端转移到服务端,没有根本上解决对头阻塞问题。
增加host请求头字段。该字段可以使得服务由一个物理主机开启的多台虚拟主机,通过host请求头找到对应虚拟主机,也就是HTTP/1.0中只能一个域名对应一条物理主机,但是HTTP/1.1中增加host字段,让一台物理主机通过子域名衍生多台虚拟主机,这样可以增加TCP连接数。
可以传输动态数据。HTTP/1.0中只能传输固定数据长度。HTTP/1.1中增加了Chunk Transfer头部字段,解决不定长数据传输问题。
HTTP/1.1 通过增加TCP的方式解决队头阻塞问题:域名分片和并发连接
HTTP/2.0
-
二进制分帧HTTP/1.x版本中都是以明文形式传输数据,在HTTP/2.0中使用二进制帧的形式传输
-
头部压缩客户端和服务端各自维护一个请求/报文头部字段的索引表,通过传输索引在查找对应的索引表,无需传输过多重复的报文头部字段
-
多路复用一条TCP连接可以同时进行多个二进制的传递,头部不同的ID标识明确请求帧,到接收到再根据标识组装成数据。
-
服务端推送不需要客户端请求,服务端主动返回信息。比如一个HTML文件中可能引用了其他css、js文件,服务端检测到会一并返回,无需等到客户端主动请求。
-
可以设置请求优先级
每个stream都可以依赖权重,可以按照依赖树分配优先级,解决关键请求被阻塞问题。
HTTP2.0中,多路复用的原理:
HTTP2.0是基于二进制“帧”的协议,而HTTP1.x是基于“文本分割”解析的协议。
HTTP1.x发送请求消息的文本格式是以换行符分割每一条
key:value的内容,解析并不断读取内容转成字节,直到遇到分割符。所以一次只能处理一个请求,在完成之前无法停止解析;并且这种数据无法预知需要多少内存。HTTP2.0将
二进制帧作为传输单元,帧的字节保存了不同信息,服务端解析HTTP/2.0的数据帧只需要解析字节。HTTP2.0是分帧的,请求和响应可以交错甚至可以复用,为了可以发送不同的“数据信息”,通过帧数据传递不同的内容,HTTP2.0中定义了10种不同类型的帧。所以HTTP2.0连接上独立、双向的帧序列交换。流ID(帧首部的6-9个字节)用来标识所需的流。
HTTP1.1中如何解决对头阻塞问题?
- 域名分片:像test.com的一级域名,可以下层分配多个二级子域名,它们可以指向同一台服务器,这样也增加了并发连接的数量。
- 并发连接:一个域名允许分配多个长连接,Chrome支持6条HTTP连接
HTTP/3.0
-
使用QUICk的UDP协议进行传输 -
无需进行多次报文握手 -- 0RTT传统的HTTP/2.0(默认开启HTTPS传输数据)需要至少3个RTT才能建立TCP连接(1RTT用于TCP三次报文握手,2次RTT用于TLS非对称加密挥手),而HTTP/3.0仅仅使用1RTT就可以传递数据,当使用缓存时,可以将RTT减为0
其实现的核心是
DH算法:-
首先客户端发送
Client Hello给服务端,请求连接 -
服务端生成g、p、a三个随机数算出A,然后将g、p、A(保留a、p、g)放到Server Config中再发送Rejection消息到客户端
-
客户端收到g、p、A后,生成随机数b, 根据g、p、b算出B,然后根据A、p、b算出初始密钥K ,然后用K加密HTTP数据,连同B一起发送给服务端。
-
服务端收到B后,根据a、p、B生成与客户端一样的密钥,解密HTTP数据。服务端会更新自己的随机数,再生成新密钥S,然后把公钥通过Server Hello发送给客户端,返回Http数据
-
客户端收到Server Hello,生成与服务端一致的新密钥S,后面传输都使用密钥S . 缓存Server Config可以实现0RTT
-
-
连接迁移传统的连接都是通过四元组(源IP、源端口、目的IP、目的端口)标识连接,其中一个发送改变,需要再次建立TCP连接,增加时延。
HTTP/3.0中使用64位的随机数(Connection ID)标识连接,只要Connection ID没有发生变化,连接依旧可以维持。
-
多路复用/队头阻塞HTTP/1.x中,TCP面向连接的协议,发送请求需要收到ACK,确认对方已经收到数据。如果每个请求都需要接收到ACK再发送新的请求效率就会降低,在HTTP/1.1中使用了pipelining的方式,允许一个TCP连接发送多个请求。
HTTP/2.0中使用二进制分帧(frame),将请求粒度减小,但是TCP层Frame组合得到Stream进行传输,一旦出现Stream中的Frame丢失,其后面的Stream就会被阻塞。
HTTP/3.0中传输单元和加密单元都是Packet,不提供可靠传输,数据包在接收端没有顺序处理,即使中间丢失一个包,也不会影响其他资源的处理,所以不会造成阻塞。
-
拥塞控制-
热拨插:TCP的拥塞控制在传输层,而QUIC可以在应用层,用户根据不同网络环境选择拥塞控制方法
-
前向纠错:将数据切割成包后对每个包进行异或运算,将运算结果随数据发送。但其中一个包丢失,可以根据另外其他包推算出
-
单调递增的Packet Number
-
ACK delay
-
-
流量控制TCP使用滑动窗口的方式对发送方的流量进行控制,而对接收方并无限制,在QUIC中补齐了这个短板。
QUIC中接收方从单条Stream和整条连接两个角度动态调整接收窗口大小。
状态码
1xx : 请求处理中,请求需要进一步处理才能完成。
101:协议升级 ,需要客户端带Upgrade请求头升级协议
2xx: 请求成功响应
200, OK成功。
204:Not Content响应没有包体,客户端无需更新当前页面。
205: Reset Content响应没有包体,客户端需更新当前页面。
206:Partial Content,使用Range协议时,断点传输。
3xx: 重定向
301 :永久重定向,在请求URL已被移除,响应的Location首部中应该包含资源现在所在的URL。
302:临时重定向,重定向到新的URL。
303:See Other,重定向默认使用get方法。
304:协商缓存,服务器资源未发生改变。
307: 临时重定向,重定向前后请求方法不变。
308: 永久重定向,重定向前后请求方法改变。
4xx: 客户端错误
400 : Bad Request 服务端任务客户端错误,但没有指名哪种错误,有可能是HTTP请求格式错误
401 : 未授权访问,客户端未提供用户账号信息
402: 支付访问
403:Forbidden 服务器理解请求,但无权限访问
404: Not Found资源未找到
408:Request Timeout 请求超时
413:请求包体超出服务器能处理的范围
5xx:服务端错误
500:Internal Server Error服务器内部发生错误
501:Not Implemented 服务器不支持请求所需功能
502:Bad Gateway 代理服务器无法获取原服务器响应
503 Service Unavailable 并发或者其他原因导致服务器尚未准备好处理当前请求
504: Gateway Timeout 代理服务超时获取原服务器
有哪些请求方法
GET:获取资源 幂等
POST,提交资源 非幂等
HEAD:大文件传输时,使用HEAD请求获取资源的元数据
OPTIONS:CORS复杂请求解决跨域问题,用到一次OPTIONS的预检请求 幂等
PUT:更新资源,带条件时是幂等的
DELETE:删除资源
CONNECT:建立tenel通道
TRACE: 回显服务器
GET和POST请求的区别
- 从
参数角度,GET请求参数是通过&分隔符连接,暴露在URL上。POST是在请求体body中
- 从
缓存角度,GET请求资源会被浏览器主动缓存,而POST不会
- 从
编码角度,GET请求按照ASCII对URL进行编码解析,但是POST请求编码没有限定
- 从
幂等角度,GET请求是幂等的,而POST不是 - 从
发送请求角度,GET会一次发送全部请求,POST请求会先发送一个请求头部信息,再发送请求体数据。
PUT和POST请求的区别
PUT更新资源或提交资源,是幂等操作,而POST不是
HTTP半全双工、WebSocket全双工的理解
HTTP是单向的,无状态协议。客户端发送请求,服务端发送响应,每条请求都与每条响应相关联。每个HTTP或HTTPS请求每次都会和服务器新建立连接,并且得到响应后,连接自行终止。
WebSocket是双向的,有状态协议,在客户端-服务端通信场景中使用的全双工协议。ws://或 为、wss://开头。它始终保持客户端和服务端的保持活动状态,直到被任何一方关闭终止。
何时使用到WebSocket?即时web应用程序(需要服务端实时发送数据)、游戏应用程序(无需刷新、服务器持续接受数据)、聊天应用程序。
WebSocket是H5提供的一种浏览器和客户端进行全双工通信的网络技术,属于应用层协议。
- 支持双向通信,更实时、更高效、更灵活、可扩展性更强。
- 较小的上下文开销。数据交换时,协议控制的数据包头部较小,在不包含头部的情况下,服务端到客户端的包头只有2-10个字节(取决于数据包长度),客户端到服务端还需要加上额外的4个字节掩码。而HTTP每次通信都需要携带完整的头部。
webScoket心跳机制
- 为了定时发送消息,使连接不超时自动断线,避免后端设置时间自动断线,需要定时发送消息给后端,让服务器知道连接还在通消息不能断
- 为了检测在正常连接的状态下,后端是正常的。
DNS预解析?
dns-prefetch提前解析可能会用到的域名,使解析结果缓存到系统缓存中,缩短DNS解析时间,提高网站访问速度。
为何?当同一时间内,有多个请求都发送给同一个服务器,那DNS会多次并且重复触发,然后浏览器才能发送请求。
dns-prefetch原理:当浏览器访问一个域名时,需要解析一个DNS,获得对应域名的ip地址。解析过程中会逐步访问:
浏览器缓存
系统缓存
- 路由器缓存
- 本地域名服务器(ISP运营商的DNS缓存)
- 根域名服务器
- 顶级域名服务器
- 权限域名服务器
dns-prefecth会将解析后的IP缓存在系统中。
DNS劫持是攻击者利用某种攻击手段,篡改某域名下的解析结果,使得该域名下的IP变成了另一个IP,导致对应的网址被重定向到了另一个不可达或假冒的网址,从而达到非法窃听用户信息或破坏正常网络服务的目的。
几种DNS攻击情况
- 在中间人(MiTM)DNS劫持攻击中,
攻击者执行中间人攻击以拦截用户和DNS服务器之间的通信并提供不同的目标IP地址,从而将用户重定向到恶意网站
- 攻击者可以
破解DNS服务器,并更改DNS记录以将DNS请求重定向到恶意站点
- 在本地DNS劫持中,攻击者在
用户系统上植入恶意软件并修改本地DNS,用户使用攻击者控制的DNS服务器,将网站域请求转换重定向到恶意站点IP地址
- 路由器DNS劫持中,攻击者
通过路由器存在的固件漏洞覆盖DNS设置,影响连接到该路由器的所有用户,攻击者甚至可以利用路由器默认密码来接管路由器
TCP如何判断丢包或者可靠传输?
TCP协议特点:面向字节流、传输可靠、面向连接
保证可靠性:
序列号: TCP传输时将每个字节的数据都进行了编号,根据编号重组报文
确认应答:TCP传输过程中,每次接受方接受到数据,都会对传输方进行确认应答(发送ACK报文),告诉发送方下次期望收到的序列号。
超时重传:基于序列号和确认应答机制,当发送方发送部分数据后,都会等待接收方发送的ACK,解析ACK报文,判断数据是否传输成功。如果长时间未收到确认报文,就启动重传机制,发送方在报文发送出去之后开始计时,超过最大等待时间,就启动重传。
流量控制:通过滑动窗口机制控制发送窗口大小,保证发送方发送的数据不要过快,让接受方可以及时接受。
拥塞控制:慢启动、拥塞避免、快恢复、快重传等算法。
TCP三次报文握手
客户端处理Closed状态,服务端处于Listen状态
- 客户端向服务端发送**
SYN**=1报文,包含初始序列号seq,进入SYN_SEND状态
- 服务端收到客户端的SYN报文,以
自己的SYN报文作为应答,指定自己的初始序列号seq,把客户端初始序列号+1作为ACK确认号,向客户端响应**SYN-ACK报文**,进入SYN_RCVD状态。
- 客户端在收到服务端的响应报文,把服务端
初始序列号+1作为确认号ACK,向服务端发送ACK报文,客户端进入ESTABLISHED状态,服务端在收到确认报文也进入ESTABLISHED。
为什么需要三次?
三次报文握手的过程是为了双方确定对方发送和接受能力的过程,通过第三次握手,服务端可以确认客户端的接受能力。
如果只有两次报文握手,可能会出现这种情况:
客户端发送一个报文后,由于开始网络阻塞,报文没有成功到达服务端,于是客户端重传报文,第二次重传的报文成功到达服务端,服务端成功响应后断开连接。这是服务端接受到了第一次请求的报文(网络好了),误认为是新的连接,向客户端发送确认报文,但是客户端忽略了服务端发送的确认报文,不发送任何数据,这是服务端一直在等待重传,这无疑极大的浪费了资源。
什么是半连接队列?
当服务端收到客户端请求并发送确认报文后,进入SYN_RCVD状态,此时双方还没有完全建立连接,服务器将这个状态下的请求连接放入一个队列,这个队列就是半连接队列
全连接队列是三次报文握手后,双方建立好连接请求的连接放入全连接队列。
SYN攻击
在三次报文握手过程中,服务端分配资源是在第二次报文握手结束时分配的,而客户端时在第三次报文握手时分配的,所以服务端易收到SYN攻击。SYN攻击就是Client在短时间内大量伪造不存在的IP地址,向服务端发送SYN报文,等待服务端回应。但是IP地址不存在,服务端不断超时重传发送ACK报文,这些伪SYN包长时间暂用半连接队列,导致正常的SYN请求因为队列满而被抛弃,从而引起网络拥塞甚至系统瘫痪。
TCP四次报文握手
客户端和服务端都处于ESTABLISHED状态,断开连接可以由任意一方发起,这里是客户端场景
- 客户端向服务端发起**
FIN报文**,指定的序列号u,进入FIN_WAIT1状态
- 服务端在收到客户端的FIN报文之后,向客户端发送**
确认报文ACK**,确认号为客户端序列号u+1,表示收到客户端报文,服务端进入CLOSE_WAIT状态,此时TCP连接处于半关闭状态,客户端收到ACK报文后进行FIN_WAIT2状态,等待服务端发送释放报文段
- 服务端若想关闭连接,向客户端发送**
FIN报文**,FIN=1, ACK=1,ack=u + 1,seq=w,服务端进入LAST_ACK状态。
- 客户端在收到服务端的FIN报文后,向服务端发送**
ACK确认报文**(ACK=1,ack=w+1,seq=u+1),客户端进入TIME_WAIT状态,经过2MSL(2个最大报文段在网络停留时长)之后,断开来连接,进入CLOSED状态。
为什么需要四次报文握手?
因为向服务端发送FIN报文后,服务端可以选择关闭或者不关闭,此时为了让客户端知道自己已经收到FIN报文,先发送一个ACK确认报文,等服务器想要关闭连接,再发送FIN报文。
等待2MSL的意义:1. 为了报文客户端发送给的最后一个ACK报文端能够到达服务器。因为如果ACK丢失了,导致处于
LAST_ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,重新启动等待计时器,如果客户端没有等待2MSL,而是发送完ACK报文之后就关闭,一旦ACK丢失,服务端将无法进入连接关闭状态。 2.防止已失效的请求报文段出现在本连接中。客户端等待2MSL,可以使本连接持续的时间内所产生的所有报文段从网络中消失,使下一个新连接不会出现旧连接的请求报文端。
HTTPS四次挥手
- 浏览器向服务端发送
client_Hello, 发送信息包含自己的加密套件和client_random随机数。
- 服务端在收到客户端发送过来的信息后,向浏览器发送
serverHello,包含确认的加密套件、server_random和数字证书。
- 浏览器在收到服务端的数字证书后,验证数字证书的合法性,将公钥从数字证书中拿出来,对浏览器生成的
pre_master进行公钥加密,向服务器发送挥手结束通知和加密的pre_master发送给服务端,然后浏览器通过client_random+server_random+pre_master生成master_secret
- 服务端在收到浏览器的pre_master后,用
私钥对它解密,然后通过client_random+server_random+pre_master生成master_secret,并向浏览器发送挥手结束通知。
- 之后双方通过生成的master_secret进行通信
数字证书是服务器向CA(权威机构)申请的。服务器向CA提供自己的网站信息、公钥等,机构拿到这些信息(明文)后,使用Hash函数计算明文信息,得到信息摘要,CA再使用自己的私钥对摘要进行加密,得到数字签名。
浏览器如何验证数字证书?
- 浏览器拿到服务器的数字证书后,读取网站明文信息,使用与
CA签名是相同的Hash函数计算,得到信息摘要A
- 使用
CA机构公钥对数字签名进行解密,得到信息摘要B
- 对比信息摘要A和信息摘要B,如果一致,说明数字证书有效,同时也会校验证书相关的域名、有效信息等
HTTP缓存
缓存分为强缓存、协商缓存和启发式缓存
强缓存特点是不需要向服务器发送HTTP请求,只需要读取浏览器缓存即可。一般含有响应头有expires、pragama、cache-control等字段,说明命中强缓存。
expires表示缓存的到期时间,格林尼治时间,缺点:判断过期时间使用的是本地时间,本地世家可以修改。
-
cache-control是HTTP/1.1中控制缓存方式的响应头部字段public表示可以使用代理缓存private表示禁止使用代理缓存no-store表示禁止使用一切缓存no-cache表示使用协商缓存来验证资源是否变更max-age表示资源可以缓存多长时间,单位ssmax-age表示代理缓存的时间
progma是HTTP1.0中禁止使用浏览器缓存的字段,在HTTP/1.1中被cache-control取代。
协商缓存特点是需要浏览器每次向服务器发送请求,看服务器的资源是否发送改变,如果没有改变,服务器返回304状态码,客户端读取浏览器缓存。如果资源发生改变,就返回新的资源和200状态码。
一般响应头有Last-Modified、ETag,请求头有If-Modified-Since、If-None-Match说明命中协商缓存。
Last-Modified表示资源在服务器最后一次被修改的时间
ETag表示服务器资源的唯一标志符号
If-Modified-Since是浏览器的请求头部字段,服务器比较两次时间,判断资源在这期间是否有被修改
If-None-Match是浏览器命中协商缓存向服务器发送请求时加上的请求头字段,表示上一次资源返回的ETag,服务器比较当前ETag和If-None-Match中的ETag
为什么存在Last-Modified了,还需要ETag?
因为有一些情况仅通过最后一次修改时间是无法验证资源实际内容是否已经改变的:
- 一些资源是周期性重写的,但实际的内容并没有发生改变
- 有一些修改信息是不重要的,比如注释等
- Last-Modified无法精确到ms, 而有一些资源的更新频率是小于一秒的。
**启发式缓存**是如果一个可以缓存的请求设置中没有expires和cache-control,但是响应头有设置Last-Modified信息,这种情况下浏览器会有一个默认的缓存策略: (Date - Last-Modified) * 0.1设置为过期时间。
缓存存在的位置:
Service Worker : 运行在浏览器背后独立于主线程的独立线程,可以用来实现缓存功能
- Service Worker必须是HTTPS协议
- 可以操控缓存
- 一般Service没命中缓存,会使用
fecth()从memory cache或disk cache获取
from memory cache: 内存缓存
- 一般是img、link等已经被抓取到的资源(预加载资源)
- 关闭会话缓存消失
from disk cache:磁盘缓存
- 根据请求响应字段判断哪些资源需要缓存,哪些资源不需要缓存直接使用
Cookie相关字段
Cookie是为了解决HTTP无状态的问题,用于在客户端保存在服务端验证用户身份的数据。
Cookie分为Session Cookie会话Cookie和Persistent Cookie永久性Cookie。
Session Cookie没有 expires和max-age等时效字段,当前会话关闭,cookie消失;而Persistent Cookie 有expires或max-age字段,存在磁盘中。
domain请求可以携带cookie的域名,只能是当前域名的上级域名,不能设置为顶级域名或者公共域名
path请求可以携带cookie的路径
HttpOnly不能使用js脚本、ajax等获取cookie
secure在HTTPS协议的情况下才能发送
同源策?如何解决跨域?
同源策略是指协议、端口、域名相同,即使是不同域名指向同一个IP地址,也是不同源。
同源限制的操作
- 跨域访问DOM
- Cookie 、 localStorage、sessionStorage
- AjAX
允许跨域访问
- img的src
- link的href
- script的src
解决跨域的方法
- JSONP
- CORS
- iframe + postMessage
- 反向代理
大文件实现断点续传
分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分割成多个数据块part来进行分片上传,每个分片都有一个唯一标识,服务端根据标志合成原始文件。
断点续传,是在下载或上传时,将下载或上传任务人为的划分为几个部分,每个部分采用一个线程进行上传或下载,如果有网络故障,可以从已经上传或下载的部分开始继续上传未完成部分,没必要从头开始上传下载。
实现思路
拿到文件,保存文件唯一性标识,切割文件,分段上传,每次上传一段,根据唯一性标识判断文件上传进度,直到文件的全部片段上传完毕
<input type="file" />
<script>
const input = document.querySelector('input');
input.addEvenetListener('change',function(){
var file = this.files[0];
});
//,d5实现文件的唯一性
const md5Code = md5(file);
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.addEventListener('load',function(e){
// 10m切割一段,实际切割需要循环切割
var slice = e.target.result.slice(0,10*1024*1024);
})
const formdata =new FormData();
formdata.append('0',slice);
formdata.append('filename', file.filename);
var xhr = new XMLHttpRequest();
xhr.addEventListener('load',function(){
})
xhr.open('POST','');
xhr.send(formdata);
xhr.addEventListener('progress',updateProgress);
xhr.upload.addEventListener('progress',updateProgress)
function updateProgress(evnet){
if(event.lengthComputable){
//进度条
}
}
</script>