HyperText Transfer Protocol,超文本传输协
- 应用层 http、ftp、dns
- 传输层, tcp、udp
- 网络层 ip
- 数据链路层 发送端(每通过一层,增加首部)从应用层往下走,接收端(每通过一层,删除首部)则往应用层往上走
- 发送端发送一个带有SYN的数据包
- 接收端收到数据包,发送SYN/ACK的数据包,传达确认信息
- 发送端回传带有ACK的数据包,结束
- 客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据
- 服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接
- 服务器端准备好关闭连接时,向客户端发送结束连接请求
- 客户端接收到来自服务器端的关闭请求,发送一个确认包,服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html
<html>
http协议版本 状态码 状态码原因短语 首部字段 回车 内容实体
获取资源
传输实体的主体
传输文件
获得报文首部
删除文件
询问支持的方法
追踪路径
每次请求都会造成无谓的tcp连接建立和断开,增加通信的开销量
HTTP keep-alive 只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。 建立一次tcp连接后,进行多次请求和响应交互 HTTP/1.1 中,所有的连接默认都是持久连接
发送请求后,不用等待响应,可直接发送下一个请求
根据服务端发送的响应报文内一个set-cookie首部字段信息,下次客户端向服务端发送请求时,客户端会自动在请求报文中 加入cookie。
- 1XX 接收的请求正在处理
- 2xx success 请求正常处理完毕
- 3xx 重定向 需要附加操作
- 4xx 客户端错误 服务器无法处理请求
- 5xx 服务器错误
请求的资源已经被分配了新的uri
客户端发送带条件的请求,服务端允许请求访问资源,但没有满足条件的情况。
错误请求,服务器不理解请求的语法,比如参数少传了
Unauthorized 未授权,访问被拒绝, 请求要求身份验证
对请求资源的访问被服务器拒绝了
无法找到请求资源
服务器内部错误
错误网关, 服务器作为网关或代理,从上游服务器收到无效响应
服务器处于超负载状态、或正在进行停机维护,无法处理请求
网关超时,服务器作为网关或代理,但是没有及时从上游服务器收到请求
客户端---代理服务器(转发)---源服务器(持有资源实体)
在缓存数据未失效的情况下,不需要再和服务器发生交互 Expires和Cache-Control
通用首部字段Cache-Control,请求报文和响应报文双方都会使用的首部 cache-Control: private, max-age=0, no-cache 参数用逗号分隔
- private 所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值。
- no-cache 虽然字面意思是“不要缓存”,但实际上还是要求客户端缓存内容的,只是是否使用这个内容由后续的对比来决定
- max-age 最大有效时间,客户端发送的指令里带max-age,如果判定资源缓存时间比指定时间小,客户端就接收缓存资源
- no-store: 真正意义上的“不要缓存”。所有内容都不走缓存 max-age=0,缓存服务器通常要把请求转发给源服务器
缺点: 时间到了但是文件没有改变,还是会去请求一次服务器
需要进行比较判断是否可以使用缓存。强制缓存优先级高于协商缓存。 流程上说,浏览器先请求缓存数据库,返回一个缓存标识。之后浏览器拿这个标识和服务器通讯。如果缓存未失效,则返回 HTTP 状态码 304 表示继续使用,于是客户端继续使用缓存;如果失效,则返回新的数据和缓存规则,浏览器响应数据后,再把规则写入到缓存数据库
- Etag & If-None-Match 返回文件的唯一标识ETag,只有当文件内容改变时,ETag才改变。 浏览器的缓存文件过期时,浏览器带上请求头(If-None-Match)相当于上一次发来的Etag 服务器比较If-None-Match和文件的ETag,一致就返回304,使用本地缓存。 不一致就返回文件内容和ETag
- Last-Modified & If-Modified-Since
- 浏览器请求,服务器返回并带上文件上次修改时间 Last-Modified
- 下一次请求相同资源时时,浏览器从自己的缓存中找出“不确定是否过期的”缓存。因此在请求头中将上次的 Last-Modified 的值写入到请求头的 If-Modified-Since 字段
- 服务器比较If-Modified-Since和文件上次修改时间。一致就返回304,使用本地缓存。 不一致返回文件内容和Last-Modified 缺陷:文件可能是服务器动态生成的
Pragma > Cache-Control > Expires > ETag > Last-Modified
- 服务端把自己的公钥key1发给证书颁发机构,向证书颁发机构申请证书
- 机构有自己的公钥和私钥,机构用自己的私钥来加密key1,然后生成一个签名证书,发给服务端
- 客户端向服务器请求时,服务器返回签名证书
- (浏览器已经维护好了各大机构的名称和公钥),客户端从本地获得对应的公钥,解密出证书签名。 按照同样的签名规则,自己也生成一个证书签名,如果两个签名一致,说明证书是有效的。 (从证书中得到明文T,数字签名S。公钥解密S===证书里的hash算法执行T) 再次用机构的公钥,解密出服务端的公钥Key1
- 浏览器生成自己的对称加密公钥key2,用服务端公钥Key1加密Key2,发给服务端
- 服务端用自己的私钥解密,得到key2,然后用key2进行对称加密
- 浏览器后退刷新的时候,get无害,post数据会被重新提交
- GET请求会被浏览器主动cache,而POST不会,除非手动设置
- GET 方法向 URL 添加数据;URL 的长度是受限制的,POST数据长度无限制
- get请求可收藏为书签,post不可以
- GET 用于获取信息,是无副作用的,是幂等的,POST 用于修改服务器上的数据,有副作用,非幂等
从上到下查找,找到就返回,没有继续
- Service Worker
- Memory Cache
- Disk Cache
- 网络请求
浏览器的 TAB 关闭后该次浏览的 memory cache 便告失效 几乎所有的请求资源 都能进入 memory cache 在从 memory cache 获取缓存内容时,浏览器会忽视例如 max-age=0, no-cache 等头部配置 不想缓存,用no-store memory cache 是浏览器为了加快读取缓存速度而进行的自身的优化行为,不受开发者控制,也不受 HTTP 协议头的约束
存储在硬盘上的缓存。 平时所说的强制缓存,协商缓存,以及 Cache-Control
- 调用 Service Worker 的 fetch 事件响应
- 查看 memory cache
- 查看 disk cache。这里又细分:
- 如果有强制缓存且未失效,则使用强制缓存,不请求服务器。这时的状态码全部是 200
- 如果有强制缓存但已失效,使用对比缓存,比较后确定 304 还是 200
- 发送网络请求,等待网络响应
- 把响应内容存入 disk cache (如果 HTTP 头信息配置可以存的话)
- 把响应内容 的引用 存入 memory cache (无视 HTTP 头信息的配置)
- 把响应内容存入 Service Worker 的 Cache Storage (如果 Service Worker 的脚本调用了 cache.put())
分级查询
- 客户端发出解析域名的请求给本地的dns服务器
- 本地域名服务器查询缓存中是否有记录,有的话就返回结果,没有的话 就把请求发给跟域名服务器,跟域名服务器会返回它所管理的域中的DNS 服务器的IP地址
- 本地服务器再向上一步返回的域名服务器发送请求,接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址
- 重复上一步,直到找到正确的记录
- 本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时还将结果返回给客户机
- HTTP1.1支持长连接和请求的流水线处理。在一个TCP连接上可以传送多个HTTP请求和响应,请求发出后不需要等待响应, 可直接发送下一个请求
- HTTP 1.1支持只发送header信息,服务器认为客户端有权限请求服务器,则返回100,否则返回401。客户端如果接受到100,才开始把请求body发送到服务器。(节约带宽)
- HTTP1.0是没有host域的,HTTP1.1才支持这个参数
- HTTP1.0主要使用if-modified-since、expires来作为缓存判断标准,HTTP1.1则引入了更多的缓存控制策略例如ETag、 if-none-match。
- HTTP2.0使用了多路复用的技术,一个连接可以并发处理多个请求
- HTTP2.0使用了头部数据(header的数据)压缩
- HTTP2.0引入了server push,它允许服务端推送资源给浏览器