HTTP 和 HTTPS

HTTP 和 HTTPS 基本概念

  • HTTP 是超文本协议,用于从服务器传输超文本到客户端的超文本协议。
  • HTTPS 是安全的 HTTP 通道,在 HTTP 下加入 SSL 层进行加密处理数据。其作用是保证数据传输的安全性和完整性。

HTTP 和 HTTPS 的区别和优缺点

  • HTTP 是超文本传输协议,明文传输数据;HTTPS 要比 HTTP 更安全,HTTPS 通过 SSL 层加密数据,在传输过程中保证数据安全,可靠,完整。
  • HTTP 默认端口 80;HTTPS 默认端口 443。
  • HTTP 连接简单,无状态;HTTPS 在握手阶段相对耗时,会增加页面加载时长。
  • HTTPS 的缓存不如 HTTP 高效。
  • HTTPS 需要 CA 证书,费用较高。
  • SSL 证书需要绑定 IP,不能在用一个 IP 上绑定多个域名,IPV4 资源支持不了这种消耗。

HTTPS 协议的工作原理

  1. 客户端使用 HTTPS url 访问服务端,服务端建立 ssl 连接
  2. 服务端接收到客户端请求后,会将网站证书(证书包含公钥)发送给客户端。
  3. 服务端和客户端开始协商 ssl 链接的安全等级
  4. 客户端建立会话密钥,然后通过公钥加密数据后发送服务端。
  5. 服务端通过私钥解密数据完成通信。

TCP 三次握手

  1. 第一次握手:建立连接时,客户端发送syn 包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
  2. 第二次握手:服务器收到 syn 包并确认客户的 SYN(ack=j+1),同时也发送一个自己的 SYN 包(syn=k),即SYN+ACK 包,此时服务器进入SYN_RECV状态。
  3. 第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP 连接成功)状态,完成三次握手。

TCP/IP 如何保证数据包传输的有序可靠

对字节流分段并进行编号然后通过  ACK 回复超时重发这两个机制来保证。

  1. 为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区。
  2. 并为每个已发送的数据包启动一个超时定时器。
  3. 如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区。
  4. 否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
  5. 接收方收到数据包后,先进行 CRC 校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。

TCP 和 UDP 的区别

  1. TCP 是面向连接的,而 UDP 是面向无连接的。
  2. TCP 仅支持单播传输,UDP 支持单播,多播,广播。
  3. TCP 传输的可靠性,UDP 面向无连接,不可靠的传输协议。
  4. UDP 传输速率比 TCP 快,实时性好。

HTTP 跨域请求问题

  • 跨域原理
    跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的。
    同源策略,是浏览器对 JavaScript 实施的安全限制,只要协议、域名、端口有任何一个不同,都被当作是不同的域。

  • 解决方案

    1. JSONP:前端构造 script 标签请求指定 URL(由 script 标签发出的 GET 请求不受同源策略限制),服务器返 回一个函数执行语句,该函数名称通常由查询参 callback 的值决定,函数的参数为服务器返回的 json 数据。该函数在前端执行后即可获取数据。
    2. 代理服务器:请求同源服务器,通过该服务器转发请求至目标服务器,得到结果再转发给前端。前端开发中测试服务器的代理功能就是采用的该解决方案,但是最终发布上线时如果 web 应用和 接口服务器不在一起仍会跨域。
    3. CORS(Cross Origin Resource Share) 跨域资源共享,后端方案
    • 响应简单请求:
      简单请求:method 为 get/post/head,并且没有自定义请求头,且 Content-Type 为 application/x-www-form-urlencoded,multipart/form-data 或者 text/plain 之一,否则都是复杂请求。

      1
      res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000')
    • 响应复杂请求:预检 preflight 请求,需要响应浏览器发出的 options 请求

      1
      2
      // 客户端,定义了自定义请求头,属于复杂请求
      axios.post('api/users', { foo: 'bar' }, { headers: { 'x-token': 'xxxxxx' } })
      1
      2
      3
      4
      5
      6
      // 服务端响应,post请求的复杂请求还需要在"Access-Control-Allow-Headers" 允许 "Content-Type"
      res.writeHead(200, {
      'Access-Control-Allow-Origin': 'http://localhost:3000',
      'Access-Control-Allow-Method': 'POST',
      'Access-Control-Allow-Headers': 'custom-header,Content-Type',
      })
    • 如果要携带 cookie 信息,则请求变为 credential 请求:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      // 客户端,为true时,服务端需要 'Access-Control-Allow-Credentials':'true'
      axios.defaults.withCredentials = true

      // credential请求,预检options中和/users接口中均需添加
      res.setHeader('Access-Control-Allow-Credentials', 'true')

      // 设置cookie
      res.setHeaders('Set-Cookie', 'cookie1=aaa')

      // 响应复杂请求
      res.writeHead(200, {
      'Access-Control-Allow-Origin': 'http://localhost:3000',
      'Access-Control-Allow-Method': 'POST',
      'Access-Control-Allow-Headers': 'custom-header,Content-Type',
      })

Cookie、sessionStorage、localStorage 区别

  • 相同点:
    存储在客户端
  • 不同点:
    • cookie 数据大小不能超过 4k;sessionStorage 和 localStorage 的存储比 cookie 大得多,可以达到 5M+
    • cookie 设置的过期时间之前一直有效;localStorage 永久存储,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage 数据在当前浏览器窗口关闭后自动删除
    • cookie 的数据会自动的传递到服务器;sessionStorage 和 localStorage 数据保存在本地

粘包问题

TCP 粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

  • 粘包出现原因
    简单得说,在流传输中出现,UDP 不会出现粘包,因为它有消息边界粘包情况有两种,一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包。

  • 为了避免粘包现象,可采取以下几种措施:

    1. 对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP 提供了强制数据立即传送的操作指令 push,TCP 软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;
    2. 对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;
    3. 由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。分包多发。
  • 以上提到的三种措施,都有其不足之处。

    1. 第一种编程设置方法虽然可以避免发送方引起的粘包,但它关闭了优化算法,降低了网络发送效率,影响应用程序的性能,一般不建议使用。
    2. 第二种方法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较高时,或由于网络突发可能使某个时间段数据包到达接收方较快,接收方还是有可能来不及接收,从而导致粘包。
    3. 第三种方法虽然避免了粘包,但应用程序的效率较低,对实时应用的场合不适合。