HTTP/1.1
断点续传和多线程下载
:::info 需要解决的问题 :::
- 客户端明确任务:从哪里开始下载
- 本地是否已有部分文件
- 文件已下载部分在服务器发生改变?
- 使用几个线程并发下载
- 本地是否已有部分文件
- 下载文件的指定部分内容
- 下载完毕后拼装成统一的文件
HTTP Range规范
描述 :允许服务器基于客户端请求只发送响应包体的一部分给客户端,客户端自行将分片组装。
- HTTP Range规范帮助实现断点续传,多线程下载,视频播放器实时拖动。
- 服务器 通过Accept-Range响应头表示是否支持Range请求
- Accept-Range = bytes 表示支持
- Accept-Range = none 不支持
- 浏览器 通过Range说明请求的字节范围
断点续传问题:如上图,服务器与浏览器通过etag头部保证文件在浏览器已下载部分的版本一致。 详见增量更新。
Cookie由服务器生成,response header携带 set-cookie 通知客户端
- 一个set-cookie 只有一个name/value pair
- response header 中可以有多个set-cookie字段
- 在收到response 后,
- cookie可以保存在磁盘或内存当中
- browser对同站点的后续请求header中带有Cookie字段,以name/value pair形式通过semicolum分隔。
- 第三方Cookie | 在引用第三方资源时,第三方服务器响应中可以携带cookie。
无状态的Rest架构、状态管理
- 应用状态应由浏览器管理
- Rest架构要求服务器不应保存应用状态
HTTP请求的状态
同源 :要求同协议、域名、端口号
隐患 :站点B收到的 (来自同一浏览器的) 请求,可能是另一个站点通过脚本发出的,会导致请求上下文(user-agent / cookie) 不安全。 :::info 安全性和可用性平衡 :::
可用性
- 通过HTML标签的src属性跨域访问
- 跨域写操作被允许
- 安全性
- cookie、local storage、IndexDB无法读取
- DOM无法获取
- AJAX无法使用 :::danger CSRF 攻击 : 基于第三方cookie 和 同源策略form表单限制 的漏洞 ::: :::success 防御CSRF 的一种解决方案 :::
CORS
Cross-Origin-Resource-Sharing :::info 简单请求 ::: 解决方案 :
- 请求中携带 Origin:host
- 响应中携带
Access-Control-Allow-Origin
表示允许哪些域 - 浏览器通过
Access-Control-Allow-Origin
决定是否放行。
:::info 其他请求 ::: 解决方案:
- 先发送
预检请求
- 发送正式请求
- 预检请求头部:
- Access-Control-Request-Method
- Access-Control-Request-Headers
- 预检请求响应
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Max-Age
正式请求:
- 请求头部:
- Origin:一个页面的资源可能来自多个域名,在AJAX等子请求中标明来源于某个域名下的脚本,以通过服务器的安全校验。
- Access-Control-Request-Method
- Access-Control-Request-Headers
- 响应头部:
- Access-Control-Allow-Origin
条件请求
目的:
- 由客户端携带条件判断信息,服务器预执行条件验证过程成功后,再返回资源的表述
应用场景:
- 缓存策略
- 断点续传中对旧内容校验
多客户端并发修改同一资源时,防止某一客户端的更新被错误丢弃 :::info Validation ::: 通过HTTP 头部实现验证。
Validator Response Header
- etag = entity-tag |
相当于所请求资源的版本号
- entity-tag = DQUOTE *content DQUOTE
- Last-Modified = HTTP-date .
标记此文件在服务器端最后被修改的时间
- DATE:
响应包体生成的时间
- etag = entity-tag |
Validator Request Header
首次缓存
- 基于过期缓存
- 第一次请求某URL时,返回200,同时携带 Last-Modified 属性标记此文件在服务器端最后被修改的时间。
- 客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会向服务器传送If-Modified-Since报头,询问该时间之后文件是否有被修改过.
- 如果服务器端的资源没有变化,返回 304(Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。
解读:
- 上图第一部分: 缓存过期,但服务端未修改,返回304,浏览器复用缓存,节省流量。
- 图中第二部分的请求:缓存过期,且服务端有最新修改,则响应中携带新的etag和last-modified。
增量更新
- 初始下载请求
- 断点续传
更新丢失问题
412 Precondition Failed 是validation 条件请求没有通过
Nginx服务器处理条件请求策略
缓存的工作机制
几个关于缓存的http头部:
请求头部:
- If-none-match = * / etag 判断是否有匹配的
- 响应头部
- Age 由 proxy 返回,表示返回的资源在 proxy 的cache中存在时长
- Cache-Control :max-age = 100 由 Server 返回