网络协议篇(四)

75 阅读3分钟

网络协议-基础知识篇

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 请求剩下的那一部分