聊聊HTTP|青训营笔记

96 阅读7分钟

“这是我参与「第四届青训营 」笔记创作活动的第4天

HTTP

什么是HTTP

  • 超文本传输协议
  • 应用层协议,基于TCP协议

截屏2022-08-04 上午9.58.08.png

  • 请求——响应模式
  • 简单可扩展
  • 无状态协议

成长一览

截屏2022-08-04 上午9.58.59.png

Method

GET请求一个指定资源的表示形式,使用GET的请求应该只被用于获取数据
POST用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用
PUT替换资源|修改资源
DELETE删除指定资源
HEAD请求一个与GET请求的响应相同的响应,但是没有响应体
CONNECT建立一个由目标资源标识的服务器隧道
OPTIONS用于描述目标资源的通信选项,
TRACE沿着到目标资源的路径进行一个消息环回测试
PATCH用于对资源应用部分修改

Method

  • Safe(安全的):不会修改服务器的数据的方法

GET\HEAD\OPTIONS

  • Idempotent(幂等的):同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。
  • 所有安全的方法都是Idempotent的

GET\HEAD\OPTIONS\PUT\DELETE

状态码

截屏2022-08-04 上午9.59.51.png

RESRful API

  • 一种API设计风格;
  1. 每一个URI代表一种资源
  2. 客户端与服务器之间传递这种资源的某种表现层
  3. 客户端通过HTTP method,对服务器端资源进行操作,实现“表现层状态转化”
请求返回码含义
GET/zoos200 OK列出所有动物园,服务器成功返回了
POST/zoos201 CREATED新建一个动物园,服务器创建成功
PUT/zoos/ID400 INVALID REQUEST更新某个动物园的信息(提供该动物园的全部信息)用户发出的请求有错误,服务器没有进行新建或修改数据的操作
DELETE/zoos/ID204 NO CONTENT删除某个动物园,删除数据成功

常用请求头

Accept接收类型,表示浏览器支持的MIME类型(对标服务端返回的Content-Type)
Content-Type客户端发送出去实体内容的类型
Cache-control指定请求和响应遵循的缓存机制,如 no-cache
Expires缓存控制,在这个时间内不会请求,直接使用缓存,服务端时间。
Max-age代表资源在本地缓存多少秒,有效时间内不会请求,而是使用缓存
If-Modified-Since对应服务器的Last-Modified,用来匹配看文件是否变动,只能精确到1s之内。
If-None-Match对应服务端的ETag,用来匹配文件内容是否改变(非常精确)
Cookie有cookie并且同域访问会自动带上
Referer该页面的来源URL(适用于所有类型的请求,会精确到详细页面地址,csrf拦截常用到这个字端)
Origin最初的请求是从哪里发起的(只会精确到端口),Origin比Referer更注重隐私。
User-Agent用户客户端的一些必要信息,如UA头部等

常用响应头

截屏2022-08-04 上午10.00.52.png

cookie

缓存

强缓存

  • Expires,时间戳

  • Cache-Control

    • 可缓存性

      • no-cache:协商缓存验证
      • no-store:不使用任何缓存
    • 到期

      • max-age:单位是秒,存储的最大周期,相对于请求的时间
    • 重新验证+重新加载

      • Must-revalidate:一旦资源过期,在成功向原始服务器验证之前,不能使用

协商缓存

  • Etag/If-None-Match:资源的特定版本的标识符,类似于指纹
  • Last-Modified/If-Modified-Since:最后修改时间

截屏2022-08-04 上午10.01.09.png

  • Set-Cookie - response

截屏2022-08-04 上午10.01.18.png

HTTP2

HTTP1的问题

  1. TCP连接数限制

对于同一个域名,浏览器最多只能同时创建 6~8 个 TCP 连接 (不同浏览器不一样)。

  • 解决方法

    • 域名分片(资源分域 <==> 把资源放在不同域名下「比如二级子域名下」针对不同域名创建连接并请求)

      • 造成问题:每个 TCP 连接本身需要经过 DNS 查询、三步握手、慢启动等,还占用额外的 CPU 和内存,对于服务器来说过多连接也容易造成网络拥挤、交通阻塞等,对于移动端来说问题更明显
  1. 线头阻塞 (Head Of Line Blocking)
  • 解决方法

    • 管线化 - pipelining
    • 问题:第一个响应慢还是会阻塞后续响应、服务器为了按序返回相应需要缓存多个响应占用更多资源、浏览器中途断连重试服务器可能得重新处理多个请求、还有必须客户端 - 代理 - 服务器都支持管线化
  1. Header 内容多,而且每次请求 Header 不会变化太多,没有相应的压缩传输优化方案
  2. 为了尽可能减少请求数,需要做合并文件、雪碧图、资源内联等优化工作,但是这无疑造成了单个请求内容变大延迟变高的问题,且内嵌的资源不能有效地使用缓存机制
  3. 明文传输不安全

HTTP2的好处

  • 二进制分层帧。

HTTP/2中通信的最小单位是帧「frame」,每个帧都包含帧头,至少也会标识出当前帧所属的数据流。

截屏2022-08-04 上午10.02.20.png

  • 多路复用

在一个 TCP 连接上,我们可以向对方不断发送帧,每帧的 stream identifier 的标明这一帧属于哪个流,然后在对方接收时,根据 stream identifier 拼接每个流的所有帧组成一整块数据。 把 HTTP/1.1 每个请求都当作一个流,那么多个请求变成多个流,请求响应数据分成多个帧,不同流中的帧交错地发送给对方,这就是 HTTP/2 中的多路复用。

    • 流的概念实现了单连接上多请求 - 响应并行,解决了线头阻塞的问题,减少了 TCP 连接数量和 TCP 连接慢启动造成的问题
  • 服务器推送

    浏览器发送一个请求,服务器主动向浏览器推送与这个请求相关的资源,这样浏览器就不用发起后续请求。

  • Header压缩

    关于 HPACK 详见: How does it work ?- HPACK

  • 应用层的重置连接

    HTTP/2 引入 RST_STREAM 类型的 frame,可以在不断开连接的前提下取消某个 request 的 stream

  • 请求优先级设置

    HTTP/2 里的每个 stream 都可以设置依赖 (Dependency) 和权重,可以按依赖树分配优先级,解决了关键请求被阻塞的问题

  • 流量控制

    每个 http2 流都拥有自己的公示的流量窗口,它可以限制另一端发送数据。对于每个流来说,两端都必须告诉对方自己还有足够的空间来处理新的数据,而在该窗口被扩大前,另一端只被允许发送这么多数据。

HTTPS

  • HTTPS:Hypertext Transfer Protocol Secure
  • 经过 TSL/SSL 加密
  • 对称加密:加密和解密都是使用同一个密钥
  • 非对称加密,加密和解密需要使用两个不同的密钥:公钥(public key)和私钥(private key截屏2022-08-04 上午9.29.50

场景分析——静态资源

  • 静态资源方案:缓存 + CDN + 文件名Hash

CDN:Content Delivery Network

通过用户就近性和服务器负载的判断,CDN确保内容以一种极为高效的方式为用户的请求提供服务。

截屏2022-08-04 上午10.02.40.png

CORS跨域

  • 一般请求分为简单请求和复杂请求,如果是复杂请求,在进行CORS之前需要发送预请求去获知服务端是否允许该跨源请求。「克服AJAX只能同源使用的限制」
  • 相关协议头

    • Access-Control-Allow-Origin
    • Access-Control-Expose-Headers
    • Access-Control-Max-Age
    • Access-Control-Allow-Credentials
    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Request-Method
    • Access-Control-Request-Headers
    • Origin

简单请求

满足条件:

  1. 请求方法是一下三种方法之一

    1. HEAD
    2. GET
    3. POST
  2. HTTP的头信息不超出以下几种字段

    1. Accept
    2. Accept-Language
    3. Content-Language
    4. Last-Event-ID
    5. Content-Type只限于三个值:application/x-www-form-urlencodedmultipart/form-datatext/plain
// 成功之后会收到如下
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
  • Access-Control-Allow-Origin:**「必须」**表示接受那些域名的请求(如果填 * 表示所有域名都可以)
  • Access-Control-Allow-Credentials:**「可选」**表示是否可以发送cookie
// 表示使用的什么HTTP请求方法
Access-Control-Request-Method: PUT 
// 表示浏览器发送的自定义字段
Access-Control-Request-Headers: X-Custom-Header
  • 结束啦,感谢观看~