网络协议-基础知识篇
1. "合法"地跨域访问
1. 简单请求和复杂请求
简单请求
- GET/POST/HEAD方法之一
- 仅能使用CORS安全的头部:Accept、Accept-Language、Content-Language、Content-Type
- Content-Type值只能是:Text/plain、multipart/form-data、application/x-www-form-urlencoded三者其中之一
复杂请求
- 访问资源前,需要先发起prefilght预检请求(方法OPTIONS)询问何种请求是被允许的的
2. 简单请求的跨域访问
- 请求中携带Origin头部告知来自哪个域名
- 响应中携带Access-Control-Allow-Origin头部表示允许哪些域名
3. 复杂请求的跨域访问
预检请求
- 预检请求头部
-
- Access-Control-Request-Method
- Access-Control-Request-Headers
- 预检响应头部
-
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Max-Age
第二次请求
- 请求头部:Origin
- 响应头部:
-
- Access-Control-Allow-Origin
- Access-Control-Allow-Credentials,告诉浏览器是否可以将Credentials暴露给客户端使用,Credentials包含cookie、authorization类头部、TLS证书等
- Access-Control-Expose-Headers,告诉浏览器哪些响应头部可以供客户端使用,默认情况下只有Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma可供使用
2. HTTP Range
1. 应用场景
- 支持断点续传
- 支持多线程下载
- 支持视频播放器实时拖动
2. 使用方式
- 服务器通过 Accept-Range 头部表示是否支持 Range 请求
-
- 例如:
-
-
- Accept-Ranges: bytes
- Accept-Ranges: none
-
- 通过Range头部传递请求范围,如:Range: bytes=0-499
- 在响应报文里用头字段“Transfer-Encoding: chunked”来表示,意思是报文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)逐个发送。
- “Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的
3. Range 条件请求
- 如果客户端已经得到了 Range 响应的一部分,并想在这部分响应未过期 的情况下,获取其他部分的响应
-
- 常与 If-Unmodified-Since 或者 If-Match 头部共同使用
- If-Range = entity-tag / HTTP-date
-
- 可以使用 Etag 或者 Last-Modified
4. 服务响应
206 Partial Content
- Content-Range 头部:显示当前片断包体在完整包体中的位置
- 例如:
-
-
Content-Range: bytes 42-1233/1234
-
Content-Range: bytes 42-1233/*
-
416 Range Not Satisfiable
- 请求范围不满足实际资源的大小,其中 Content-Range 中的 complete- length 显示完整响应的长度,例如:
-
- Content-Range: bytes */1234
200 OK
- 服务器不支持 Range 请求时,则以 200 返回完整的响应包体
5. 多重范围与 multipart
- 请求:
-
- Range: bytes=0-50, 100-150
- 响应:
-
- Content-Type:multipart/byteranges; boundary=...
6. 多段下载、断点续传
要点是:
- 先发个 HEAD,看服务器是否支持范围请求,同时获取文件的大小;
- 开 N 个线程,每个线程使用 Range 字段划分出各自负责下载的片段,发请求传输数据;
- 下载意外中断也不怕,不必重头再来一遍,只要根据上次的下载记录,用 Range 请求剩下的那一部分