04-网络 应用层 HTTP、websocket

HTTP(HyperText Transfer Protocol,超文本传输协议)和 HTTPS(安全套接字层超文本传输协议)

谈谈你对 HTTP 协议的认识。

浏览器本质:socket 客户端遵循 HTTP 协议

HTTP 协议本质:通过 \r\n 分割的规范 + 请求响应之后断开链接 ==> 无状态、短连接

具体一点就是 HTTP 协议是建立在 TCP 之上的,是一种规范,它规范定了发送的数据的数据格式,然而这个数据格式是通过 \r\n 进行分割的,请求头与请求体也是通过2个 \r\n 分割的,响应的时候,响应头与响应体也是通过 \r\n 分割,并且还规定已请求已响应就会断开链接,即—> 短连接、无状态

HTTP 报文

HTTP 报文是 HTTP 协议交互时所规定请求和响应的规则。请求端(客户端)向响应端(服务器端)请求的发送的信息叫做请求报文,响应端(服务器端)反馈请求端(客户端)的叫做响应报文

HTTP 请求报文 ★★★★★

请求报文的格式:请求行 + 请求头 + 空行 + 请求体

  • 请求行:请求方法 + 请求URL + HTTP 协议版本

    • 请求方法:常见的 HTTP 请求方法有 GET、POST、DELETE、HEAD、OPTIONS、PUT、TRACE
    • 示例:POST /s?ie=utf-8 HTTP/1.1
  • 常见的请求头:

    • Accept:客户端可识别的响应内容类型列表。
    • Accept-Language:客户端可接收的自然语言。
    • Accept-Encoding:客户端可接收的编码压缩格式。
    • Accept-Charset:可接收的应答的字符集。
    • Authorization:用于超文本传输协议的认证的认证信息。
    • Connection:连接方式(close 或 keepalive)。
    • Cookie:存储于客户端扩展字段,向同一域名的服务器端发送属于该域的 cookie。
    • Content-Type:响应类型。
    • Content-MD5:请求体的内容的二进制 MD5 散列值,以 Base64 编码的结果。
    • Content-Length:内容长度。
    • Host:请求的主机名,允许多个域名同处一个IP 地址,即虚拟主机。
    • Reference:来源。
    • User-Agent:浏览器类型。
  • 空行:空行必须有

  • 请求体:

    • GET 的请求体为空。
    • POST 的请求体可以不为空,如下 username=admin&password=admin

HTTP 响应报文 ★★★★★

HTTP 的响应报文是服务器返回给我们的数据,必须先有请求报文再有响应报文。

响应报文的格式:响应行 + 响应头 + 空行 + 响应体

  • 响应行: 报文协议及版本 + 状态码 + 状态描述

    • 示例:HTTP/1.1 200 OK
  • 响应头:

    • Content-Type:text/html;charset=utf-8
    • Content-length:2048
  • 空行:空行必须有

  • 响应体:响应体会以 HTML 形式返回

列举 HTTP 请求中常见的请求方式 ★★★★★

HTTP 请求方法有 8 种:

  1. GET:获取数据。
  2. POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的创建和/或已有资源的修改。
  3. HEAD:HEAD 与 GET 类似,但不返回实际的响应主体。它主要用于获取资源的元数据,检查资源是否存在以及验证资源是否被修改。
  4. OPTIONS:获取后台服务器支持的 HTTP 的通信方式;对跨域请求进行 preflight request(预检请求)。
  5. PUT:向指定资源上传最新的内容
  6. DELETE:请求服务器删除 Request-URI 所标识的资源。
  7. TRACE:TRACE 用于沿着目标资源的路径执行消息环回测试;它回应收到的请求,以便客户可以看到中间服务器进行了哪些(假设任何)进度或增量。主要用于测试或诊断。
  8. CONNECT:要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。主要使用 SSL(安全套接层)和 TLS(传输层安全) 协议把通信内容加密后经网络隧道传输。HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。

GET 方法与 POST 方法的区别 ★★★

  • 语义(主要区别):GET 通常用于获取或查询资源,而 POST 通常用于创建或修改资源。
  • 幂等:GET 请求是幂等的,即多次重复执行不会改变资源的状态,而 POST 请求是不幂等的,即每次执行可能会产生不同的结果或影响资源的状态。
  • 格式:GET 请求的参数通常放在 URL 中,形成查询字符串(querystring),而 POST 请求的参数通常放在请求体(body)中,可以有多种编码格式,如 application/x-www-form-urlencoded、multipart/form-data、application/json 等。GET 请求的 URL 长度受到浏览器和服务器的限制,而 POST 请求的 body 大小则没有明确的限制。不过,实际上 GET 请求也可以用 body 传输数据,只是并不推荐这样做,因为这样可能会导致一些兼容性或者语义上的问题。
  • 缓存:由于 GET 请求是幂等的,它可以被浏览器或其他中间节点(如代理、网关)缓存起来,以提高性能和效率。而 POST 请求则不适合被缓存,因为它可能有副作用,每次执行可能需要实时的响应。
  • 安全性:GET 请求和 POST 请求如果使用 HTTP 协议的话,那都不安全,因为 HTTP 协议本身是明文传输的,必须使用 HTTPS 协议来加密传输数据。另外,GET 请求相比 POST 请求更容易泄露敏感数据,因为 GET 请求的参数通常放在 URL 中。

列举 HTTP 请求中的状态码 ★★★★★

  1. 1xx Informational(信息性状态码)
    使用 websocket、HTTP2.0、跨域的时候会用到

  2. 2xx Success(成功状态码)

    • 200 OK:请求被成功处理。比如我们发送一个查询用户数据的 HTTP 请求到服务端,服务端正确返回了用户数据。这个是我们平时最常见的一个 HTTP 状态码。
    • 201 Created:请求被成功处理并且在服务端创建了一个新的资源。比如我们通过 POST 请求创建一个新的用户。
    • 202 Accepted:服务端已经接收到了请求,但是还未处理。
    • 204 No Content:服务端已经成功处理了请求,但是没有返回任何内容。
  3. 3xx Redirection(重定向状态码)

    • 301 Moved Permanently:资源被永久重定向了。比如你的网站的网址更换了。
    • 302 Found:资源被临时重定向了。比如你的网站的某些资源被暂时转移到另外一个网址。
  4. 4xx Client Error(客户端错误状态码)

    • 400 Bad Request:发送的 HTTP 请求存在问题。比如请求参数不合法、请求方法错误。
    • 401 Unauthorized:未认证却请求需要认证之后才能访问的资源。
    • 403 Forbidden:直接拒绝 HTTP 请求,不处理。一般用来针对非法请求。
    • 404 Not Found:你请求的资源未在服务端找到。比如你请求某个用户的信息,服务端并没有找到指定的用户。
    • 409 Conflict:表示请求的资源与服务端当前的状态存在冲突,请求无法被处理。
  5. 5xx Server Error(服务端错误状态码)

    • 500 Internal Server Error:服务端出问题了(通常是服务端出 Bug 了)。比如你服务端处理请求的时候突然抛出异常,但是异常并未在服务端被正确处理。
    • 502 Bad Gateway:我们的网关将请求转发到服务端,但是服务端返回的却是一个错误的响应。

cookie、session ★★★★★

  • cookie 是由 Web 服务器保存在用户浏览器上的文件(key-value格式),可以包含用户相关的信息。客户端向服务器发起请求,就提取浏览器中的用户信息由 HTTP 发送给服务器。
  • session 是浏览器和服务器会话过程中,服务器会分配的一块储存空间给 session。服务器默认为客户浏览器的 cookie 中设置 sessionid,这个 sessionid 就和 cookie 对应,浏览器在向服务器请求过程中传输的 cookie 包含 sessionid,服务器根据传输 cookie 中的 sessionid 获取出会话中存储的信息,然后确定会话的身份信息。

cookie 与 session 区别

  1. cookie 数据存放在客户端上,安全性较差,session 数据放在服务器上,安全性相对更高。
  2. 单个 cookie 保存的数据不能超过 4K,session 无此限制信息后,使用自己的私钥进行解密。由于非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,非常的慢。

Cookie 被禁用怎么办?

最常用的就是利用 URL 重写把 Session ID 直接附加在 URL 路径的后面。

localStorage、sessionStorage ★★★

在 HTML5 中,引入了两个新的前端存储特性:localStorage、sessionStorage。

这两者非常相似,都是用来在前端保存一定量的数据,称为前端存储,但是这两者仍然存在一定区别:

  • 生命周期:

    • localStorage: localStorage 的生命周期是永久的,即使关闭页面、浏览器,其中的内容也不会消失,除非手动删除 localStorage 中的内容。
    • sessionStorage: sessionStorage 的生命周期是一次浏览器窗口会话,浏览器窗口指的是一组同源页面(来自于一个域名)的浏览器页面集合,当这些窗口全部关闭之后,sessionStorage 的内容将不会存在。
  • 存储大小:

    • 两者都为5MB/域名
  • 存储位置:

    • 两者都保存在客户端,不与服务器进行交互
  • 存储内容类型:

    • 两者都只能存储字符串,但是可以通过类型转换来存储各类数据
  • 获取方式:

    • localStorage: window.localStorage
    • sessionStorage: window.sessionStorage

可见 localStorage 适合在前端存储长时间使用的数据,而 sessionStorage 适合存储短期使用、一次性的数据

另外这里要提一句,sessionStorage 并不是 session:

  • sessionStorage 中的‘session’是指浏览器窗口会话,而后者的‘session’指的是服务器会话
  • 前者是前端存储,与服务器无关,而后者的实现依赖于服务器

URI 和 URL 的区别是什么?

  • URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。
  • URL(Uniform Resource Locator) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。
    1
    2
    3
    4
    5
    6
    7
    8
    scheme://host[:port#]/path/.../[;url-params][?query-string][#anchor]
    scheme //有我们很熟悉的http、https、ftp以及著名的ed2k,迅雷的thunder等。
    host //HTTP服务器的IP地址或者域名
    port //HTTP服务器的默认端口是80,这种情况下端口号可以省略。如果使用了别的端口,必须指明,例如tomcat的默认端口是8080 http://localhost:8080/
    path //访问资源的路径
    url-params //所带参数
    query-string //发送给http服务器的数据
    anchor //锚点定位

URI 的作用像身份证号一样,URL 的作用更像家庭住址一样。URL 是一种具体的 URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。

HTTP 与 HTTPS 介绍

HTTP 协议被用于在 Web 浏览器和网站服务器之间传递信息,HTTP 协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP 协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

为了解决 HTTP 协议的这一缺陷,需要使用另一种协议:HTTPS,为了数据传输的安全,HTTPS 在 HTTP 的基础上加入了 SSL/TLS 协议,SSL/TLS 依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

HTTPS 协议是由 SSL/TLS+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 HTTP 协议安全。

HTTPS 协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。

HTTPS 优化

  1. HSTS 重定向技术:将 HTTP 自动转换为 HTTPS,减少 301 重定向。
  2. TLS 握手优化:在 TLS 握手完成前客户端就提前向服务器发送数据。
  3. 会话标识符:服务器记录下与某客户端的会话 ID,下次连接客户端发 ID 过来就可以直接用之前的私钥交流了。
  4. OSCP Stapling:服务器将带有 CA 机构签名的 OCSP 响应在握手时发给客户端,省的客户端再去 CA 查询。
  5. 完全前向加密 PFS:使用更牛逼复杂的秘钥算法。

HTTPS 和 HTTP 的区别 ★★★

  1. HTTPS 需要到 CA 申请证书,一般免费证书较少,因而需要一定费用。功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
  2. HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL/TLS 加密传输协议。
  3. HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
  4. HTTP 的连接很简单,是无状态的;HTTPS 是由 SSL/TLS+HTTP 构建的可进行加密传输、身份认证的网络协议,比 HTTP 安全。
  5. HTTPS 是构建在 SSL/TLS 之上的 HTTP 协议,所以 HTTPS 会消耗更多的服务器资源。
  6. HTTPS 握手阶段比较费时,会使页面的加载时间延长近 50%,增加 10% 到 20% 的耗电。
  7. SSL 证书通常需要绑定 IP,不能在同一 IP 上绑定多个域名,IPv4 资源不可能支撑这个消耗。
  8. HTTPS 的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL 证书的信用链体系并不安全,特别是在某些国家可以控制 CA 根证书的情况下,中间人攻击一样可行。
  9. 搜索引擎通常会更青睐使用 HTTPS 协议的网站,因为 HTTPS 能够提供更高的安全性和用户隐私保护。使用 HTTPS 协议的网站在搜索结果中可能会被优先显示,从而对 SEO 产生影响。

HTTP/1.0 和 HTTP/1.1 有什么区别?

  • 连接方式 : HTTP/1.0 为短连接,HTTP/1.1 支持长连接。HTTP 协议的长连接和短连接,实质上是 TCP 协议的长连接和短连接。
  • 状态响应码 : HTTP/1.1 中新加入了大量的状态码,光是错误响应状态码就新增了 24 种。比如说,
    • 100 (Continue)——在请求大资源前的预热请求
    • 206 (Partial Content)——范围请求的标识码,
    • 409 (Conflict)——请求与当前资源的规定冲突,
    • 410 (Gone)——资源已被永久转移,而且没有任何已知的转发地址。
  • 缓存机制 : 在 HTTP/1.0 中主要使用 Header 里的 If-Modified-Since,Expires 来做为缓存判断的标准,HTTP/1.1 则引入了更多的缓存控制策略例如 Entity tag,If-Unmodified-Since, If-Match, If-None-Match 等更多可供选择的缓存头来控制缓存策略。
  • 带宽:HTTP/1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP/1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
  • Host 头(Host Header)处理 :HTTP/1.1 引入了 Host 头字段,允许在同一 IP 地址上托管多个域名,从而支持虚拟主机的功能。而 HTTP/1.0 没有 Host 头字段,无法实现虚拟主机。

HTTP/1.1 和 HTTP/2.0 有什么区别?

HTTP 2.0 相比于 HTTP 1.X,可以说是大幅度提高了 web 的性能。

在 HTTP 1.X 中,为了性能考虑,我们会引入雪碧图、将小图内联、使用多个域名等等的方式。这一切都是因为浏览器限制了同一个域名下的请求数量,当页面中需要请求很多资源的时候,队头阻塞(Head of line blocking)会导致在达到最大请求数量时,剩余的资源需要等待其他资源请求完成后才能发起请求。

可以感受下 HTTP 2.0 比 HTTP 1.X 到底快了多少。

  • 在 HTTP 1.X 中,因为队头阻塞的原因,你会发现请求是这样的
  • 在 HTTP 2.0 中,因为引入了多路复用,你会发现请求是这样的

在 HTTP 2.0 中,有两个非常重要的概念,分别是帧(frame)、流(stream)。帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。

  • 多路复用(Multiplexing):HTTP/2.0 在同一连接上可以同时传输多个请求和响应(可以看作是 HTTP/1.1 中长链接的升级版本),互不干扰。HTTP/1.1 则使用串行方式,每个请求和响应都需要独立的连接,而浏览器为了控制资源会有 6-8 个 TCP 连接都限制。这使得 HTTP/2.0 在处理多个请求时更加高效,减少了网络延迟和提高了性能。
  • 二进制帧(Binary Frames):HTTP/2.0 使用二进制帧进行数据传输,而 HTTP/1.1 则使用文本格式的报文。二进制帧更加紧凑和高效,减少了传输的数据量和带宽消耗。
  • 头部压缩(Header Compression):HTTP/1.1 支持 Body 压缩,Header 不支持压缩。HTTP/2.0 支持对 Header 压缩,使用了专门为 Header 压缩而设计的 HPACK 算法,减少了网络开销。在两端维护了索引表,用于记录出现过的 header ,后面在传输过程中就可以传输已经记录过的 header 的键名,对端收到数据后就可以通过键名找到对应的值。
  • 服务器推送(Server Push):HTTP/2.0 支持服务器推送,可以在客户端请求一个资源时,将其他相关资源一并推送给客户端,从而减少了客户端的请求次数和延迟。而 HTTP/1.1 需要客户端自己发送请求来获取相关资源。

HTTP/2.0 多路复用效果图(图源: HTTP/2 For Web Developers):

HTTP/2 Multiplexing

可以看到,HTTP/2.0 的多路复用使得不同的请求可以共用一个 TCP 连接,避免建立多个连接带来不必要的额外开销,而 HTTP/1.1 中的每个请求都会建立一个单独的连接。

HTTP/2.0 和 HTTP/3.0 有什么区别?

  • 传输协议:HTTP/2.0 是基于 TCP 协议实现的,HTTP/3.0 新增了 QUIC(Quick UDP Internet Connections) 协议来实现可靠的传输,提供与 TLS/SSL 相当的安全性,具有较低的连接和传输延迟。你可以将 QUIC 看作是 UDP 的升级版本,在其基础上新增了很多功能比如加密、重传等等。HTTP/3.0 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了 QUIC。
  • 连接建立:HTTP/2.0 需要经过经典的 TCP 三次握手过程(由于安全的 HTTPS 连接建立还需要 TLS 握手,共需要大约 3 个 RTT)。由于 QUIC 协议的特性(TLS 1.3,TLS 1.3 除了支持 1 个 RTT 的握手,还支持 0 个 RTT 的握手)连接建立仅需 0-RTT 或者 1-RTT。这意味着 QUIC 在最佳情况下不需要任何的额外往返时间就可以建立新连接。
  • 队头阻塞:HTTP/2.0 多请求复用一个 TCP 连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求。由于 QUIC 协议的特性,HTTP/3.0 在一定程度上解决了队头阻塞(Head-of-Line blocking, 简写:HOL blocking)问题,一个连接建立多个不同的数据流,这些数据流之间独立互不影响,某个数据流发生丢包了,其数据流不受影响(本质上是多路复用+轮询)。
  • 错误恢复:HTTP/3.0 具有更好的错误恢复机制,当出现丢包、延迟等网络问题时,可以更快地进行恢复和重传。而 HTTP/2.0 则需要依赖于 TCP 的错误恢复机制。
  • 安全性:在 HTTP/2.0 中,TLS 用于加密和认证整个 HTTP 会话,包括所有的 HTTP 头部和数据负载。TLS的工作是在 TCP 层之上,它加密的是在 TCP 连接中传输的应用层的数据,并不会对 TCP 头部以及 TLS 记录层头部进行加密,所以在传输的过程中 TCP 头部可能会被攻击者篡改来干扰通信。而 HTTP/3.0 的 QUIC 对整个数据包(包括报文头和报文体)进行了加密与认证处理,保障安全性。

HTTP/1.0、HTTP/2.0 和 HTTP/3.0 的协议栈比较:

http-3-implementation

WebSocket

谈谈你对 WebSocket 协议的认识。

WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。

HTTP 是一种无状态,无连接,单向的应用层协议,它采用了请求/响应模型,通信请求只能由客户端发起,服务端对请求做出应答处理。这样的弊端显然是很大的,只要服务端状态连续变化,客户端就必须实时响应,都是通过 javascript 与 ajax 进行轮询,这样显然是非常麻烦的,同时轮询的效率低,非常浪费资源(http 一直打开,一直重复的连接)。

于是就有了 WebSocket,它是一种全面双工通讯的网络技术,任意一方都可以建立连接将数据推向另一方,WebSocket 只需要建立一次连接,就可以一直保持。数据通过 \r\n 分割,让客户端和服务端创建连接后不断开、验证+数据加密

本质: 协议本质上是应用层的协议,就是一个创建连接后不断开的 socket,当连接成功后,客户端(浏览器)会自动向服务端发送消息,服务端接收后,会对该数据加密 base64(sha1(swk+magic_string)) 并构造响应头,然后发送给客户端

Websocket 示意图

框架中是如何使用 WebSocket 的?

  • django:channel
  • flask:gevent-websocket
  • tornado:内置

WebSocket 的优缺点?

  • 优点:代码简单,不再重复创建连接
  • 缺点:兼容性没有长轮询好,如 IE 会有不兼容

WebSocket 的常见应用场景:

WebSocket 和 HTTP 的区别

WebSocket 和 HTTP 两者都是基于 TCP 的应用层协议,都可以在网络中传输数据。

下面是二者的主要区别:

  • WebSocket 是一种双向实时通信协议,而 HTTP 是一种单向通信协议。并且,HTTP 协议下的通信只能由客户端发起,服务器无法主动通知客户端。
  • WebSocket 使用 ws://wss://(使用 SSL/TLS 加密后的协议,类似于 HTTP 和 HTTPS 的关系) 作为协议前缀,HTTP 使用 http://https:// 作为协议前缀。
  • WebSocket 可以支持扩展,用户可以扩展协议,实现部分自定义的子协议,如支持压缩、加密等。
  • WebSocket 通信数据格式比较轻量,用于协议控制的数据包头部相对较小,网络开销小,而 HTTP 通信每次都要携带完整的头部,网络开销较大(HTTP/2.0 使用二进制帧进行数据传输,还支持头部压缩,减少了网络开销)。

什么是 WebSocket 中的 magic string

客户端向服务端发送消息时,会有一个 sec-websocket-keymagic string 的随机字符串(魔法字符串),服务端接收到消息后会把他们连接成一个新的 key 串,进行编码、加密,确保信息的安全性。

WebSocket 的工作过程是什么样的?

WebSocket 的工作过程可以分为以下几个步骤:

  1. 客户端向服务器发送一个 HTTP 请求,请求头中包含 Upgrade: websocketSec-WebSocket-Key 等字段,表示要求升级协议为 WebSocket;
  2. 服务器收到这个请求后,会进行升级协议的操作,如果支持 WebSocket,它将回复一个 HTTP 101 状态码,响应头中包含 Connection: UpgradeSec-WebSocket-Accept: xxx 等字段、表示成功升级到 WebSocket 协议。
  3. 客户端和服务器之间建立了一个 WebSocket 连接,可以进行双向的数据传输。数据以帧(frames)的形式进行传送,WebSocket 的每条消息可能会被切分成多个数据帧(最小单位)。发送端会将消息切割成多个帧发送给接收端,接收端接收消息帧,并将关联的帧重新组装成完整的消息。
  4. 客户端或服务器可以主动发送一个关闭帧,表示要断开连接。另一方收到后,也会回复一个关闭帧,然后双方关闭 TCP 连接。

另外,建立 WebSocket 连接之后,通过心跳机制来保持 WebSocket 连接的稳定性和活跃性。

SSE 与 WebSocket 有什么区别?

摘自Web 实时消息推送详解

SSE 与 WebSocket 作用相似,都可以建立服务端与浏览器之间的通信,实现服务端向客户端推送消息,但还是有些许不同:

  • SSE 是基于 HTTP 协议的,它们不需要特殊的协议或服务器实现即可工作;WebSocket 需单独服务器来处理协议。
  • SSE 单向通信,只能由服务端向客户端单向通信;WebSocket 全双工通信,即通信的双方可以同时发送和接受信息。
  • SSE 实现简单开发成本低,无需引入其他组件;WebSocket 传输数据需做二次解析,开发门槛高一些。
  • SSE 默认支持断线重连;WebSocket 则需要自己实现。
  • SSE 只能传送文本消息,二进制数据需要经过编码后传送;WebSocket 默认支持传送二进制数据。

SSE 与 WebSocket 该如何选择?

SSE 好像一直不被大家所熟知,一部分原因是出现了 WebSocket,这个提供了更丰富的协议来执行双向、全双工通信。对于游戏、即时通信以及需要双向近乎实时更新的场景,拥有双向通道更具吸引力。

但是,在某些情况下,不需要从客户端发送数据。而你只需要一些服务器操作的更新。比如:站内信、未读消息数、状态更新、股票行情、监控数量等场景,SEE 不管是从实现的难易和成本上都更加有优势。此外,SSE 具有 WebSocket 在设计上缺乏的多种功能,例如:自动重新连接、事件 ID 和发送任意事件的能力。

SSL/TLS

TLS 协议位于传输层之上,应用层之下。首次进行 TLS 协议传输需要两个 RTT,接下来可以通过 Session Resumption 减少到一个 RTT。

在 TLS 中使用了两种加密技术,分别为:对称加密、非对称加密

  • 对称加密: 对称加密就是两边拥有相同的秘钥,两边都知道如何将密文加密解密。
  • 非对称加密: 有公钥私钥之分,公钥所有人都可以知道,可以将数据用公钥加密,但是将数据解密必须使用私钥解密,私钥只有分发公钥的一方才知道。

TLS 握手过程如下:

  1. client 向 server 发送请求 https://baidu.com,然后连接到 server 的 443 端口,发送的信息主要是

    • 随机值1
    • 客户端支持的加密算法
    • 支持的协议版本,比如 TLS 1.2 版
    • 一个 session id,标识是否复用服务器之前的 tls 连接(需要服务器支持)
  2. server 接收到信息之后给予 client 响应握手信息,包括

    • 随机值2
    • 确认使用的加密通信协议版本,比如 TLS 1.2 版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信
    • 匹配好的协商加密算法,这个加密算法一定是 client 发送给 server 加密算法的子集
    • 一个 session id(若同意复用连接)
  3. 随即 server 给 client 发送第二个响应报文是数字证书。server 必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面,这套证书其实就是一对公钥和私钥。
    传送证书,这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间、server 端的公钥,第三方证书认证机构(CA)的签名,server 端的域名信息等内容。

  4. client 解析证书,这部分工作是由 client 的 TLS 来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值(预主秘钥)。

  5. client 认证证书通过之后,接下来是通过 随机值1随机值2预主秘钥 组装会话秘钥。然后通过证书的公钥加密会话秘钥。

  6. client 传送加密信息,这部分传送的是用证书加密后的会话秘钥,目的就是让 server 使用秘钥解密得到 随机值1随机值2预主秘钥

  7. server 解密得到随机值1随机值2预主秘钥,然后组装会话秘钥,跟客户端会话秘钥相同。

  8. client 通过会话秘钥加密一条消息发送给服务端,主要验证服务端是否正常接受客户端加密的消息。

  9. 同样 server 也会通过会话秘钥加密一条消息回传给客户端,如果客户端能够正常接受的话表明 SSL 层连接建立完成了。

通过以上步骤可知,在 TLS 握手阶段,两端使用非对称加密的方式来通信,但是因为非对称加密损耗的性能比对称加密大,所以在正式传输数据时,两端使用对称加密的方式通信。

数字签名的制作过程:

  1. CA 机构拥有非对称加密的私钥和公钥。
  2. CA 机构对证书明文数据 T 进行 hash。
  3. 对 hash 后的值用私钥加密,得到数字签名 S。

明文 T 和数字签名 S 共同组成了数字证书,这样一份数字证书就可以颁发给网站了。

那浏览器拿到服务器传来的数字证书后,如何验证它是不是真的?(有没有被篡改、掉包)

浏览器验证过程:

  1. 拿到证书,得到明文 T、签名 S。
  2. 用 CA 机构的公钥对 S 解密(由于是浏览器信任的机构,所以浏览器保有它的公钥。详情见下文),得到 S’。
  3. 用证书里指明的 hash 算法对明文 T 进行 hash 得到 T’。
  4. 显然通过以上步骤,T’ 应当等于 S’,除非明文或签名被篡改。所以此时比较 S’ 是否等于 T’,等于则表明证书可信。

QUIC

这是一个谷歌出品的基于 UDP 实现的同为传输层的协议,目标很远大,希望替代 TCP 协议。

  • 该协议支持多路复用,虽然 HTTP 2.0 也支持多路复用,但是下层仍是 TCP,因为 TCP 的重传机制,只要一个包丢失就得判断丢失包并且重传,导致发生队头阻塞的问题,但是 UDP 没有这个机制。
  • 实现了自己的加密协议,通过类似 TCP 的 TFO 机制可以实现 0-RTT,当然 TLS 1.3 已经实现了 0-RTT 了。
  • 支持重传和纠错机制(向前恢复),在只丢失一个包的情况下不需要重传,使用纠错机制恢复丢失的包。
    • 纠错机制:通过异或的方式,算出发出去的数据的异或值并单独发出一个包,服务端在发现有一个包丢失的情况下,通过其他数据包和异或值包算出丢失包
    • 在丢失两个包或以上的情况就使用重传机制,因为算不出来了

DNS(Domain Name Service,域名服务)

在网上,所有的地址都是 IP 地址,但这些 IP 地址太难记了,所以就出现了域名(比如 http://baidu.com)。而域名解析就是将域名转换为 IP 地址的这样一种行为。例如:访问 www.baidu.com,实质是把域名解析成 IP。

你可以把域名看成是某个 IP 的别名,DNS 就是去查询这个别名的真正名称是什么。

DNS 的作用是什么?

DNS(Domain Name System)域名管理系统,是当用户使用浏览器访问网址之后,使用的第一个重要协议。DNS 要解决的是域名和 IP 地址的映射问题

DNS:域名系统

在一台电脑上,可能存在浏览器 DNS 缓存,操作系统 DNS 缓存,路由器 DNS 缓存。如果以上缓存都查询不到,那么 DNS 就闪亮登场了。

目前 DNS 的设计采用的是分布式、层次数据库结构,DNS 是应用层协议,它可以在 UDP 或 TCP 协议之上运行,端口为 53

DNS 服务器有哪些?根服务器有多少个?

DNS 服务器自底向上可以依次分为以下几个层级(所有 DNS 服务器都属于以下四个类别之一):

  • 根 DNS 服务器。根 DNS 服务器提供 TLD 服务器的 IP 地址。目前世界上只有 13 组根服务器,我国境内目前仍没有根服务器。
  • 顶级域 DNS 服务器(TLD 服务器)。顶级域是指域名的后缀,如 comorgnetedu 等。国家也有自己的顶级域,如 ukfrca。TLD 服务器提供了权威 DNS 服务器的 IP 地址。
  • 权威 DNS 服务器。在因特网上具有公共可访问主机的每个组织机构必须提供公共可访问的 DNS 记录,这些记录将这些主机的名字映射为 IP 地址。
  • 本地 DNS 服务器。每个 ISP(互联网服务提供商)都有一个自己的本地 DNS 服务器。当主机发出 DNS 请求时,该请求被发往本地 DNS 服务器,它起着代理的作用,并将该请求转发到 DNS 层次结构中。严格说来,不属于 DNS 层级结构

世界上并不是只有 13 台根服务器,这是很多人普遍的误解,网上很多文章也是这么写的。实际上,现在根服务器数量远远超过这个数量。最初确实是为 DNS 根服务器分配了 13 个 IP 地址,每个 IP 地址对应一个不同的根 DNS 服务器。然而,由于互联网的快速发展和增长,这个原始的架构变得不太适应当前的需求。为了提高 DNS 的可靠性、安全性和性能,目前这 13 个 IP 地址中的每一个都有多个服务器,截止到 2023 年底,所有根服务器之和达到了 600 多台,未来还会继续增加。

DNS 劫持了解吗?如何应对?

DNS 劫持是一种网络攻击,它通过修改 DNS 服务器的解析结果,使用户访问的域名指向错误的 IP 地址,从而导致用户无法访问正常的网站,或者被引导到恶意的网站。DNS 劫持有时也被称为 DNS 重定向、DNS 欺骗或 DNS 污染。DNS 劫持详细介绍可以参考:黑客技术?没你想象的那么难!——DNS 劫持篇

  • 手动修改 DNS 地址。清除DNS缓存。
  • 使用 ip 地址访问。
  • 使用 http dns。

简述 SSH 的整个过程。

SSH 为 ‘Secure Shell’ 的缩写,是建立在应用层基础上的安全协议。

SSH 是目前较可靠,为远程登录会话和其他网络服务提供的安全性协议。

利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。


04-网络 应用层 HTTP、websocket
https://flepeng.github.io/interview-10-网络-04-网络-应用层-HTTP、websocket/
作者
Lepeng
发布于
2020年8月8日
许可协议