网咯协议-HTTP协议

HTTP演进

HTTP 1.0(废弃)

  • 无状态:不跟踪不记录请求的状态;
  • 无连接:每次请求都需要建立连接(不支持长连接);
  • 队头阻塞:请求全部同步处理,处理请求后,发送响应,接受到ACK,再处理下一个请求;
  • 端口易耗尽:主动断开一方,必须经过2个MSL的TIME_WAIT状态;
  • 仅支持文本内容;不支持图片、视频;

HTTP 1.1(使用广泛)

  • 默认长连接:增加了Connection,设置为keep-alive保持长连接;默认保持;
    • 但是连接利用率低,一个域下一般为6个连接;
    • 长连接依赖TCP,TCP建立链接后,双发不主动发送
      FIN
      包,保持 
      ESTABLISHED
       状态
  • 管道化技术:将多个请求通过一个TCP连接发送,但是响应仍要顺序接收,不解决队头阻塞
    • 为了能够并发处理多个资源的响应,在开发层面就出现了很多操作:雪碧图;
  • 缓存:允许浏览器缓存响应,在资源无变化的情况下,可以直接使用缓存;缓存有失效时间;
  • 断点续传:增加Header
  • 支持图片、视频、音频;

HTTP 2.0

  • 二进制帧:HTTP2将原来的报文中的Header和Body变为
    首部帧
    数据帧
    ,以二进制的格式传输
  • 流标识符:每个二进制帧都有一个流标识符,可以乱序接收响应,再通过流标识符进行整合;(解决了应用层面的队头阻塞,无法解决TCP的队头阻塞)
    • 在二进制帧和流标识符的基础上,HTTP2就可以在同一个HTTP连接中并发处理请求响应,实现:多路复用
  • 头部压缩:使用HPack压缩头部;
  • 安全性增强:HTTP2基于HTTPS,加密传输;
  • 主动推送:在客户端请求资源时,如发现一些连带的资源会主动推送给客户端,如:css、js等资源;

一次完整HTTP请求

  1. 域名解析:指定域名请求后,需要将域名解析为服务器的ip地址;
    • 如果是浏览器发起的HTTP,会先从浏览器缓存中搜索;其次是操作系统的DNS缓存;然后是hosts文件,最后是递归查询域名服务器;
  2. 建立TCP连接(三次握手)
  3. TCP连接建立完成后,构建并发起HTTP请求;
  4. 服务器接受HTTP请求,路由解析、业务逻辑处理,最后返回响应;
  5. 客户端接受响应;
    • 如果是浏览器请求HTML:浏览器边解析边渲染:DOM渲染、加载资源(CSS、JS)
    • 如果是服务器请求,正常拿到响应后处理业务逻辑;
  6. 断开HTTP连接(HTTP 1.1之后默认保持长连接),以下情况会断开连接:
    • 明确指定
      Connection: close
    • 连接超时,由
      keep-Alive: timeout=xx
      指定;
    • 客户端或服务器主动关闭请求;
    • 网络异常;
  7. 执行4次挥手断开HTTP连接;

HTTP Status Code

2xx Success Code: indicate that the request was successfully received and processed.

2xx表明请求已被成功接收并处理

  • 200 OK: The standard response for successful requests.
  • 201 Created: Signifies that a new resource has been successfully created.
  • 204 No Content: Indicates that the server successfully processed the request, but is not returning any content.

3xx Redirection Code: signify that further action needs to be take by the browser in order to fulfill the requests.

300系列提示浏览器需要一些额外操作才能满足请求

  • 301 Moved Permanently: The URL of the requested resource has been changed permanently. The new URL is given in the response.
    • 永久重定向原地址切换为新的重定向的地址;并且浏览器记住原地址,再次访问原地址则直接重定向,不会再请求服务端;
  • 302 Found: Indicates that the resource is temporarily located at another URL.
    • 临时重定向地址栏保持原地址,仅仅是向重定向的地址请求资源;浏览器不会记住这个操作,后续每次访问原地址,都会向服务端请求一次;
  • 304 Not Modified: Informs the client that the cashed version of the response is still valid and can be used.

4xx Client Error Code: 400 series indicate the requests contains bad syntax.

4xx表明请求包含语法错误无法被处理

  • 400 Bad Request: The server cannot process the request due to a client error.
  • 401 Unauthorized: Authentication is required for the requests to be completed.
  • 403 Forbidden: The server understands the request but refuses to authorize it.
  • 404 Not Found: The server can not find the resource.
  • 429 Too Many Requests: The user has sent too many requests in a given amount of time( rate limiting )

5xx Server Error Code: 500 series indicate that something went wrong on the server.

5xx表示服务端存在问题

  • 500 Internal Server Error.
  • 501 Not Implemented: The server does not support the functionality required to fulfill the request.
  • 503 Service Unavailable: The server is not ready to handle the request, often used the maintenance or overloaded servers.

HTTP会话机制

HTTP是无状态的,每次通信都是独立的(长连接只是省去建立连接的损耗),服务端要知道每次请求的额外状态信息就需要其他机制;

Cookie:是服务器发送到客户端存储的一段数据,用于跟踪用户状态;

  • Cookie由Key-Value构成,明文存储,公开,可修改;通常存储一些公开信息,用于识别用户身份;
  • 服务端在返回HTTP响应前,可以通过
    Set-cookie
    来写入Cookie(键值对的方式写入),浏览器后续在相同的域下,会自动携带对应的Cookie;
  • Cookie的大小、安全、过期、跨域校验等都由浏览器控制和保证
  • Cookie存储:带有expires保存在磁盘中;不带有expires则临时放在内存;

Cookie的弊端:

  1. 安全问题:
    1. 名文存储:如果网站的保持登录功能仅由Cookie实现,Cookie被窃取则可以直接登录;
    2. CSRF攻击:第三方恶意站点,诱导用户发起A站点请求,可以直接携带A站点的Cookie完成请求,如果A站点没有其他防护,可能攻击成功。因此涉及资金、安全等操作仍然要二次验证;
  2. 容量有限:Cookie的容量由浏览器支持,通常单个域的Cookie大小限制在4KB。过大的Cookie在用户量大时,对服务器是一种开销。

Session

为了解决Cookie的问题,对应的,需要服务端也维护会话数据,session就是其中一种方案;

  • Session机制是需要基于Cookie的,需要浏览器通过Cookie携带sessionId;服务器通过sessionId来识别当前的请求状态;(用户信息等)
  • 服务端会在首次登录后,生成SessionId存储在服务端,并且放一份到Cookie中;
  • 之后客户端的请求中的Cookie需要携带SessionId,服务端就能在服务端的存储中识别到用户的登录时间、敏感信息等;也就实现了控制用户的登录时长。

Session弊端:

  1. 服务器存储开销:需要额外的存储开销;DB或缓存;
  2. 分布式环境共享问题:分布式环境下,用户的请求是被负载均衡后路由到后端服务器,此时服务器要想获取对应的session,就需要将session维护在中心服务中;
  3. 依赖Cookie:服务端要考虑跨域问题。

Token机制

Token是一种无状态的会话方案;将用户信息签名后,在客户端和服务器间传输以识别身份。token方案只是协议机制,非具体方案,等同于http中加了个Header;JWT(Json Web Token)是Token的一种最主流的解决方案;

  • JWT的数据通常会进行签名,防止数据篡改,可将登陆时间放到Token,就可以下线用户;
  • Token不依赖浏览器策略,可以跨域、不会自动被浏览器放到请求头(防范CSRF)。
  • 服务端无存储压力、无状态;
  • 很多开放接口的身份识别,就是使用JWT,定时获取token来执行接口的调用;获取token一般需要key、secret,相当于了账号密码。

弊端:

  1. 服务端不可控:服务端不维护状态的话,就没办法主动失效token;(可以用版本号方案,每个token携带一个版本号,如果token内的数据变更,则递增版本号,来失效旧Token)
  2. Token是明文公开的。无法存储敏感信息;

重要的请求头

  1. HttpOnly
    :控制Cookie能否被前段JavaScript读取;
    • 设置为
      true
      禁止前端 JavaScript 脚本读取或修改该Cookie,可以降低XSS攻击的风险;
    • 不能防止XSS攻击,但能防止使用XSS攻击来获取用户Cookie;
    • 比如XSS攻击者并不获取Cookie,而是直接在恶意JavaScript中直接请求某些重要接口,也是可以成功的(因此重要接口不能仅依赖Cookie)
    • 如果前端一定要通过JS读取Cookie(用户的个性化设置、多窗口共享状态等),但同时又有些Cookie是要设置
      HttpOnly
      的,就比较复杂,需要根据
      path
      来将Cookie拆分,不同的path使用不同的Cookie。但通常太复杂,一般是建议前端不要将Cookie作为存储介质,而是使用
      sessionStorage
      /
      localStorage
      、全局状态管理器内存存储;