1.TCP 与 UDP 的区别?
TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protocol,用户数据报协议)都属于传输层协议,其中 TCP 是一种面向连接、基于字节流通信的全双工协议,能保证端到端数据传输的可靠性;UDP 是一种不可靠且无连接基于数据报通信的协议,两者区别如下:
| TCP | UDP |
|---|---|
| 面向连接 | 无连接 |
| 可靠性高 | 不保证可靠性,但是效率高 |
| 一次传输大量报文 | 一次传输少量报文 |
| 协议复杂 | 协议简单 |
2.TCP 三次握手?
由于 TCP 提供可靠的通信机制,在传输数据之前,必须先初始化一条客户端到服务端的 TCP 连接,在连接正式建立后,双方经 TCP 连接通道进行数据传输。理论上建立传输连接只需要一个请求和一个响应。但是,实际网络通信可能导致请求或响应丢失,可采用超时重传解决此问题,即请求或响应的丢失会造成定时器超时溢出,客户端将被迫再次发起连接请求,通过重传连接请求来建立连接,但是这样可能会导致重复连接。为了避免这些问题,在建立 TCP 连接时采用三次握手(Three-way Handshake)方法避免建立重复连接。该方法要求对所有报文段进行编号,每次建立连接都产生一个新的初始序列号。
- 第一次握手:客户端向服务器发送一个 SYN 报文,请求建立连接。SYN 报文中含有序列号(Seq)字段,该字段指定了客户端下一次传输数据的序列号(每次握手都会产生一个新的序列号,用于防止旧的报文段被重复使用并被重新传送)。同时,客户端进入 SYN_SEND(同步发送)状态,等待服务器的确认。SYN 是一个标志位(flag),SYN=1 表示这个数据段是一个同步(SYN)报文。
- 第二次握手:服务器收到客户端的 SYN 报文后,发回一个 SYN+ACK 报文确认收到,并向客户端发送自己的 SYN 报文。SYN+ACK 报文中含有确认字段(Ack)和序列号字段(Seq),确认字段的值为客户端 SYN 报文的序列号+1,序列号字段则是服务器下一次传输数据的序列号。服务器进入 SYN_RECV(同步接收)状态。SYN 是一个标志位(flag),SYN=1 表示这个数据段是一个同步(SYN)报文。ACK 也是一个标志位(flag),ACK=1 表示这个 TCP 数据段是一个确认(ACK)数据段。
- 第三次握手:客户端收到服务器的 SYN+ACK 报文后,将确认号字段(Ack)设为服务器 SYN 报文的序列号+1,序列号字段为客户端第一次握手产生的序列号+1,并向服务器发送确认报文(ACK)。客户端进入 ESTABLISHED(建立连接)状态,表示连接已建立。
TCP 的三次握手是必须的,因为它能够确保双方的通信能够顺利进行并且可以防止一些网络问题的出现。通过三次握手,双方能够建立一个可靠的连接,使得数据能够在双方之间可靠地传输。如果只进行一次握手,服务器无法确定客户端是否收到了其发出的 SYN 数据包,也无法确定客户端的接收能力是否正常。如果只进行两次握手,那么可能会发生一些问题,例如客户端发送了一个连接请求,但是此时网络延迟较长,客户端并没有收到服务器的回复,而此时客户端直接开始发送数据,这时服务器会收到一个没有进行三次握手的连接请求,这可能会导致数据传输的错误。因此,TCP 建立连接必须进行三次握手,以确保通信的可靠性。
3.TCP 四次挥手过程?
TCP(Transmission Control Protocol)的四次挥手是为了确保双方在连接关闭时能够完全释放相关资源,并保证数据的可靠传输。TCP 的四次挥手过程如下:
- 第一次挥手(FIN1):客户端发送一个 TCP 报文,设置 FIN(Finish)标志位,表示客户端不再发送数据。
- 第二次挥手(ACK1):服务器接收到客户端的 FIN 后,发送一个确认的 ACK(Acknowledgment)报文,表示服务器已经收到了客户端的关闭请求。
- 第三次挥手(FIN2):服务器发送一个带有 FIN 标志的 TCP 报文,表示服务器也不再发送数据,即服务器也准备关闭连接。
- 第四次挥手(ACK2):客户端接收到服务器的 FIN 后,发送一个确认的 ACK 报文,表示客户端已经收到了服务器的关闭请求。
TCP 的四次挥手与 TCP 的半连接和保证数据可靠性相关:
- 半关闭状态: 在第一次挥手后,客户端不再发送数据,但服务器仍然可能有数据需要发送给客户端,所以需要第二次挥手来告知客户端服务器已经准备好关闭。
- 保证数据可靠性:在第三次挥手后,服务器不再发送数据,但需要等到客户端发送确认的 ACK 报文后,确认客户端已经收到了服务器的关闭请求,然后才能完成关闭。这是为了保证双方都能确认彼此已经准备好关闭连接,防止数据的丢失。
TCP 的四次挥手过程确保了在关闭连接时的有序、可靠的方式,防止数据的丢失和连接资源的泄漏。
4.什么是 TCP 滑动窗口机制?
TCP(Transmission Control Protocol)滑动窗口机制是一种用于流量控制和拥塞控制的技术。它通过动态调整发送方和接收方之间的窗口大小,实现了可靠的数据传输。滑动窗口机制的基本思想是允许发送方在接收方确认之前发送多个数据段,并根据接收方的反馈动态地调整发送窗口的大小。这种方式提高了网络的利用率和传输效率。滑动窗口的步骤如下:
- 发送窗口(Sender Window): 发送方维护一个发送窗口,用于存放已发送但未收到确认的数据。窗口的大小可以动态调整。
- 接收窗口(Receiver Window):接收方维护一个接收窗口,用于存放已接收但未按顺序交付给上层应用的数据。窗口的大小可以动态调整。
- 流量控制:滑动窗口机制通过接收方通知发送方自己的接收窗口大小,从而实现流量控制。发送方不会发送超过接收方窗口大小的数据。
- 拥塞控制:滑动窗口机制还可以通过拥塞窗口(Congestion Window)来实现拥塞控制。拥塞窗口大小取发送窗口大小和网络拥塞程度的较小值,以防止在网络拥塞时发送过多的数据。
- 动态调整:发送窗口和接收窗口的大小可以根据网络的情况进行动态调整。通过不断地接收确认和通告窗口大小的信息,发送方和接收方可以根据网络的状况逐步调整窗口的大小,以达到更好的性能和效率。
5.什么是 UDP 伪首部?
UDP 伪首部是一个用于计算 UDP 校验和的虚拟协议头,它由源 IP 地址、目的 IP 地址、协议号、UDP 数据包长度等字段组成。在计算 UDP 校验和时,UDP 伪首部会被包括在内。UDP 伪首部的作用是提高 UDP 数据包的传输可靠性。由于 UDP 协议本身并不提供可靠性保证,因此在数据包传输过程中可能会出现错误或丢失。通过使用 UDP 伪首部来计算校验和,可以检测出数据包在传输过程中是否被篡改或丢失,从而保证数据的完整性和可靠性。
UDP 伪首部中包括源 IP 地址和目的 IP 地址等信息,这些信息可以帮助接收方判断数据包的来源和目的地,以便进行处理和响应。同时,UDP 伪首部中的协议号字段可以告诉接收方该数据包使用的是 UDP 协议,从而能够正确地处理该数据包。
6.为什么 UDP 的首部比较简单?
TCP 和 UDP 都是传输层协议,它们的数据包(数据段)都有各自的首部。TCP 首部包含 20 个字节以上的数据,而 UDP 首部则只包含 8 个字节。这是因为 TCP 协议建立端到端的可靠连接,必须保证数据的完整性、有序性、控制拥塞等,因此需要更多的控制字段来实现这些功能,TCP 的首部中包含了源端口、目的端口、序列号、确认号、标志位、窗口大小等字段。但是 UDP 协议是面向无连接的,不需要保证数据的可靠性、有序性,因此只需要在首部中包含简单的源端口、目的端口、长度、校验和等字段就可以了。 因此,UDP 的首部比 TCP 的少得多,但是因为 UDP 不保证数据的完整性,因此在使用 UDP 传输数据时需要注意数据的有效性和完整性。
7.什么是 HTTP 协议?
HTTP(Hypertext Transfer Protocol)是一种用于在计算机之间传输超文本(hypertext)数据的协议。它是一种无状态、无连接的协议,通常用于在客户端和服务器之间进行通信,用于获取网页、图像、视频、音频等资源。HTTP 是建立在 TCP(Transmission Control Protocol)之上的应用层协议。它基于请求-响应模型,其中客户端向服务器发送请求,服务器收到请求后返回相应的数据。HTTP 的通信过程如下:
- 建立连接:客户端与服务器之间通过 TCP 建立连接。默认情况下,HTTP 使用端口 80。
- 发送请求:客户端向服务器发送一个 HTTP 请求,请求中包含了请求方法(GET、POST 等)、请求的资源路径、HTTP 版本以及其他相关信息。
- 服务器处理请求:服务器收到请求后,根据请求中的信息,执行相应的操作,如查询数据库、处理业务逻辑等。
- 发送响应:服务器将处理结果封装在一个 HTTP 响应中,包含了响应状态码、响应头和响应体,然后发送给客户端。
- 关闭连接:一次 HTTP 通信完成后,连接会被关闭,这使得 HTTP 是一种无连接协议。每次通信都是独立的,服务器不会保留客户端的连接状态。
8.HTTP 与 HTTPS 的区别?
HTTPS 是 Hypertext Transfer Protocol Secure 的简称,是一种网络安全传输协议。在 HTTP 协议中数据传输是明文,很容易出现安全和隐私方面的问题,例如:
- 容易遭受攻击: HTTP 的数据传输是明文的,即未经加密的。这使得传输的数据容易被中间人攻击者截获和窃听。攻击者可以轻松地获取用户提交的敏感信息,如登录凭据、个人信息等。
- 数据篡改:由于数据是以明文传输的,攻击者有可能在传输过程中修改传输的数据,这导致了数据的完整性受到威胁。攻击者可以对数据包进行篡改,从而引入恶意内容或改变原始数据。
- 身份伪造: 在 HTTP 中,没有对通信双方进行身份验证的机制。这意味着攻击者可以伪造一个 HTTP 请求,冒充合法用户或伪装成合法服务器,从而进行恶意操作。
- Cookie 安全性: HTTP 中使用的 Cookie 是在客户端存储的文本文件,它包含用户的会话信息。由于 HTTP 不提供加密,攻击者可以通过窃取 Cookie 来获取用户的会话信息,从而冒充用户进行攻击。
- 无法防止重放攻击: 由于 HTTP 请求本身没有防止重放攻击的机制,攻击者可以通过截获并重新发送以前的请求,重复执行某些操作,造成安全问题。
为了解决这些安全和隐私问题,Netscape 在 1994 年提出了 HTTPS 协议,HTTPS 使用 TLS(Transport Layer Security,传输层安全性)或 SSL(安全套接字层)协议对数据进行加密,提供身份认证,并保护通信双方之间的数据完整性。通过采用 HTTPS,可以更好地保护用户隐私,防止数据窃听和篡改,以及提供更安全的网络通信。HTTPS 通信的过程如下:
- 客户端请求: 用户在浏览器中输入一个以 "https://" 开头的网址,发起 HTTPS 请求。
- 服务器证书:服务器收到请求后,会将自己的数字证书发送给客户端。数字证书中包含了服务器的公钥、证书的有效期、颁发者等信息。
- 证书验证:客户端收到服务器的证书后,会对其进行验证。验证包括检查证书的合法性、是否过期、是否由可信的证书颁发机构(CA,Certificate Authority)签发等。
- 密钥协商:如果证书验证通过,客户端生成一个随机的对称密钥,然后使用服务器的公钥对其进行加密,发送给服务器。服务器使用自己的私钥解密得到对称密钥。
- 建立加密通道:双方现在都有了共享的对称密钥,用于加密和解密通信内容。客户端和服务器都通知对方开始使用加密通道进行通信。
- 安全数据传输:接下来的通信过程中,客户端和服务器使用共享的对称密钥对数据进行加密和解密。这保障了在网络上传输的数据的机密性和完整性。
HTTPS 传输过程过程使用非对称加密(用于证书验证和密钥协商)和对称加密(用于实际数据传输)结合的方式,确保了通信的安全性。HTTPS 与 HTTP 协议的区别如下:
- HTTP 采用明文传输,传输数据都是未加密的,因此安全性较差。HTTPS 数据传输过程使用 TLS/SSL 协议进行加密,安全性好。
- 使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构)申请证书,一般免费证书较少,因而需要一定费用。
- HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS 除了 TCP 的三个包,还要加上 SSL 握手需要的 9 个包,所以一共是 12 个包。
- HTTP 与 HTTPS 的默认端口不一样,HTTP 默认端口是 80,HTTPS 是 443。
9.说说 HTTP 缓存?
HTTP 缓存又称浏览器缓存,是指当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有"要请求资源"的副本,则会从浏览器缓存中读取,从而跳过从原始服务器中读取该资源。HTTP 缓存分为协商缓存和强缓存两种:
- 强缓存:用户发送的请求,直接从用户客户端缓存读取,不发送到服务端,无需与服务端交互。命中缓存后返回 200 状态码,且 F5 刷新浏览器不会使强缓存失败。强缓存一般应用于改动较少的资源,例如图片、CSS、JavaScript 脚本等资源,该资源的请求 URL 上一般会携带一个版本号或 hash 戳用于更新强缓存。
- 协商缓存:用户发送的请求会发送到服务端,由服务端根据参数判断是否让客户端从客户端缓存读取。协商缓存无法减少请求开销,但可减少返回的正文大小。命中缓存后返回 304 状态码,F5 刷新浏览器会使协商缓存失效。协商缓存需要配合强缓存使用,如果不启用强缓存的话,协商缓存根本没有意义。
强制缓存在缓存数据未失效的情况下(即 Cache-Control 的 max-age 没有过期或者 Expires 的缓存时间没有过期),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。强制缓存生效时,http 状态码为 200。这种方式页面的加载速度是最快的,性能也是很好的,但是在这期间,如果服务器端的资源修改了,则无法获取到最新的资源,因为它不会再向服务器发请求了。 强缓存可通过请求头的 Pragma、Cache-Control、Expires 设置:
- Pragma:Pragma 是一个在 HTTP/1.0 中规定的通用首部,这个首部的效果依赖于不同的实现,所以在"请求-响应"链中可能会有不同的效果。它用来向后兼容只支持 HTTP/1.0 协议的缓存服务器,那时候 HTTP/1.1 协议中的 Cache-Control 还没有出来。
- Cache-Control:通用消息头字段,被用于在 HTTP 请求和响应中,通过指定指令来实现缓存机制。缓存指令是单向的,这意味着在请求中设置的指令,不一定被包含在响应中。
- Expires:用于设置资源过期时间(一个 GMT 时间),如果在 Cache-Control 响应头设置了 "max-age" 或者 "s-max-age" 指令,那么 Expires 头会被忽略。
当第一次请求时服务器返回的响应头中没有 Cache-Control 和 Expires,或者 Cache-Control 和 Expires 过期及它的属性设置为 no-cache 时(即不走强缓存),那么浏览器第二次请求时就会与服务器进行协商,与服务器端对比判断资源是否进行了修改更新。如果服务器端的资源没有修改(通过 Etag/If-None-Match 和 Last-Modified/If-Modified-Since 作为缓存判断依赖),那么就会返回 304 状态码,告诉浏览器可以使用缓存中的数据,这样就减少了服务器的数据传输压力。如果数据有更新就会返回 200 状态码,服务器就会返回更新后的资源并且将缓存信息一起返回。跟协商缓存相关的 header 头属性有(ETag/If-None-Match 、Last-Modified/If-Modified-Since)请求头和响应头需要成对出现,ETag/If-None-Match 是根据请求资源内容是否变化来判断是否命中缓存,而 Last-Modified/If-Modified-Since 则根据请求资源根据最后修改时间来判断是否命中缓存。
- Etag:Etag 是 HTTP 响应头是资源的特定版本的标识符,一般是一个 hash 戳,用于描述资源的内容。Etag 可以让缓存更高效,并节省带宽,因为如果内容没有改变,Web 服务器不需要发送完整的响应。而如果内容发生了变化,使用 ETag 有助于防止资源的同时更新相互覆盖。
- If-None-Match:If-None-Match 是一个条件式请求首部。对于 GETGET 和 HEAD 请求方法来说,当且仅当服务器上没有任何资源的 ETag 属性值与 If-None-Match 相匹配的时候,服务器端才会返回所请求的资源,响应码为 200 。如果 Etag 与 If-None-Match 相匹配时则返回从缓存中返回资源,并响应 304 状态码。
- Last-Modified:资源最后一次修改时间。
- If-Modified-Since:是一个条件式请求首部。是上一次的 Last-Modified。
10.HTTP/2 有哪些特性?
HTTP/2 于 2015 年发布,是 HTTP/1.1 的继任者,改进了 HTTP1.1 性能和安全问题。HTTP2.0 主要特性如下:
- 二进制分帧传输。HTTP1.1 是一个文本协议,虽然可读性好易于调试,但传输内容体积也更大,HTTP2.0 为了优化传输效率,采用二进制形式。HTTP2.0 请求与响应数据被分割更小的二进制帧(frames,帧是最小的数据单位,每个帧都包含一个特定类型的数据块),而不再使用文本形式传输。在 HTTP2.0 中,多个帧之间可以乱序发送,根据帧首部的流可以进行重新组装。
- 引入了流(Stream)的概念。HTTP/2 中引入了流的概念,每个流都是一个独立的双向通信通道,可以用来传输帧。多个流可以在同一个连接上并行传输,而不会相互干扰。流可以根据优先级进行排序,以确保重要数据的及时传输。
- 多路复用。HTTP/2 使用单个连接来处理多个请求和响应,而不需要在每次请求之后建立新连接。这降低了连接建立和断开的开销。在 HTTP/1.1 中,浏览器和服务器之间的每个请求都需要一个独立的连接。这意味着在下载多个资源时,浏览器必须同时打开多个连接,这会导致连接的延迟和资源浪费。而 HTTP/2 中的多路复用允许多个请求和响应在单个连接上并行传输,减少了连接产生的开销,提升了通信效率。
- 支持头部压缩。在 HTTP1.X 中,HTTP 头都是以纯文本的形式发送的,通常会给每个请求增加 500-8000 字节的负荷,造成不必要带宽浪费和资源消耗。例如 cookie,默认情况下,浏览器会在每次请求的时候,把 cookie 附在 header 上面发给服务器。HTTP2 中为了减少传输不必要的请求头,使用 HPACK 压缩算法来减小请求和响应头部的大小,避免额外的带宽浪费,从而提升传输效率。
- 支持服务器推送。HTTP/2.0 的服务器推送(Server Push)是一项强大的特性,它允许服务器在客户端请求之前主动向客户端推送额外的资源。HTTP2 服务器推送的工作原理如下:
- 当客户端发起对某个资源的请求时,服务器可以检查该请求所对应的页面或资源,并判断哪些其他资源可能会被客户端在不久的将来请求。
- 服务器可以主动将这些附加资源推送到客户端,以帮助客户端更快地加载页面。服务器会在响应头部使用特殊的 PUSH_PROMISE 帧来标识推送资源,并在后续的帧中传送这些资源。
- 客户端可以选择接受或拒绝服务器推送的资源。如果客户端已经有了相同资源的本地副本,它可以拒绝接受推送的资源。
- 支持流量优先级(Stream Prioritization)。HTTP/2 允许客户端指定请求的优先级,以确保重要资源优先加载。
11.HTTP GET 与 POST 请求的区别?
GET 和 POST 是 HTTP 最主要的两个请求,其区别如下:
- 传输参数位置:GET 请求将传输参数附加在 URL 的末尾,通常以问号(?)开始,参数之间使用“&”符号分隔。而 POST 请求将数据包含在请求的请求体中。
- 应用场景:GET 请求用于从服务器获取数据,通常用于读取资源,如查看网页、下载文件、获取搜索结果等,因此 GET 请求是幂等的。POST 主要用于向服务器提交数据,执行对服务器状态的修改或进行其他需要数据传输的操作,因此是非幂等性的。
- 安全性:由于 GET 请求的参数以明文形式显示在 URL 中,因此不适合传输敏感信息,安全性比较差。而 POST 请求传输的数据包含在请求体中,并不会明文显示在 URL 中,因此安全性更高。此外,可以使用 HTTPS 来加密 POST 请求的数据,提高安全性。
- 缓存:GET 请求可以被浏览器缓存,以提高性能和减少重复请求。POST 请求默认情况下不会被浏览器缓存,因为它们通常会产生副作用,如修改服务器上的数据。
12.HTTP 常用状态码有哪些?
- 100(Continue)。100 状态码表示请求继续,客户端应继续其请求。
- 101(Switching Protocols)。101 状态码表示切换协议。服务器根据客户端的请求切换协议,只能切换到更高级的协议,例如切换到 HTTP 的新版本协议。
- 200(OK)。200 状态码表示请求成功。一般用于 GET 与 POST 请求。
- 204(No Content)。204 状态码表示无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档。
- 301(Moved Permanently)。301 状态码表示永久移动。请求的资源已被永久的移动到新 URI,返回信息会包括新的 URI,浏览器会自动定向到新 URI,今后任何新的请求都应使用新的 URI 代替。
- 302(Found)。302 状态码表示临时移动。与 301 类似,但资源只是临时被移动,客户端应继续使用原有 URI。
- 304(Not Modified)。304 状态码表示未修改,所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源。
- 307(Temporary Redirect)。307 状态码表示临时重定向,与 302 类似,使用 GET 请求重定向。
- 400(Bad Request)。400 状态码表示客户端请求的语法错误,服务器无法理解。
- 401(Unauthorized)。401 状态码表示请求要求用户的身份认证。
- 403(Forbidden)。403 状态码表示服务器理解请求客户端的请求,但是拒绝执行此请求。
- 404(Not Found)。404 状态码表示服务器无法根据客户端的请求找到资源。
- 500(Internal Server Error)。500 状态码表示服务器内部错误,无法完成请求。
- 502(Bad Gateway)。502 状态码表示错误网关。作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应。
- 504(Gateway Time-out)。504 表示网关超时,充当网关或代理的服务器,未及时从远端服务器获取请求。
13.什么是 DNS?
DNS(Domain Name System,域名系统)是互联网上用于将域名(如www.example.com)映射到对应 IP 地址的分布式数据库系统。它充当了一个将易记的域名转换为计算机能够理解的 IP 地址的服务,同时也提供了反向查询,即根据 IP 地址查找对应的域名。DNS 可以实现以下功能:
- 域名解析: DNS 将用户输入的域名翻译成计算机能够理解的 IP 地址。这样,用户不需要记住一长串数字,而是可以使用易记的域名来访问网站。
- IP 地址的反向解析: DNS 可以根据 IP 地址查询对应的域名。这在一些安全和网络管理的场景中很有用。
- 负载均衡: DNS 可以用于实现负载均衡,将用户的请求分发到不同的服务器上。通过在 DNS 记录中配置多个服务器的 IP 地址,并使用一些策略如轮询或权重分配,可以实现负载均衡。
- 域名注册信息:DNS 保存了域名的注册信息,包括域名所有者、注册商等。
DNS 解析流程如下:当用户输入一个域名时,操作系统首先查询本地 DNS 缓存,如果没有找到,则向本地 DNS 服务器发起查询请求。如果本地 DNS 服务器也没有缓存该域名的信息,它会向根 DNS 服务器发起查询,根 DNS 服务器返回顶级域名服务器的地址,然后依次迭代查询,最终找到目标域名对应的 IP 地址。查询结果会被缓存,以提高后续的解析速度。
14.什么是 CDN?
CDN(Content Delivery Network,内容分发网络)是一种通过在全球范围内分布节点服务器,将内容(如静态文件、图片、视频等)缓存并分发到靠近用户的位置,减少了数据传输的距离和时间,从而提高内容传输速度和用户访问体验的网络架构。CDN 不仅可以实现内容缓存和分发,也支持如下功能:
- 支持负载均衡机制。允许将用户的请求分散到多个服务器上,防止单一服务器成为瓶颈,提高整体系统的稳定性和性能。
- 支持加速动态内容。除了缓存静态内容,一些高级的 CDN 还提供动态内容加速服务,通过一系列技术手段减少动态内容的响应时间,例如智能路由、TCP 优化等。
- 更好的安全性。CDN 提供一些安全性特性,如 DDoS(分布式拒绝服务攻击)防护、Web 应用防火墙等,以保护源服务器免受网络攻击。
什么是XSS?
XSS(Cross-Site Scripting,跨站脚本攻击)是一种在网页中注入恶意脚本代码的攻击方式。攻击者通过向网站注入恶意的 JavaScript(或 HTML、SVG、事件属性等脚本),在用户的浏览器中执行,用于窃取用户的 Cookie、Token、敏感信息和模拟用户行为(伪造请求、操作账户)。XSS主要分为三种类型:
- 反射型 XSS:恶意脚本来自当前 HTTP 请求(如 URL 参数),服务器直接返回,诱使用户点击恶意链接。
- 存储型 XSS:恶意脚本被存储到服务器(如数据库),当其他用户访问正常页面时,脚本从服务器加载并执行(危害最大)。
- DOM 型 XSS:整个攻击过程在浏览器端完成,不涉及服务器。前端 JavaScript 代码(如 innerHTML、location.hash)不安全地操作 DOM,插入了恶意内容。
常见的解决措施:
- 对输入进行转义:但关键在于输出编码。根据输出位置(HTML 内容、HTML 属性、JavaScript、URL)使用不同的编码规则。
- 充分利用 CSP(内容安全策略):告诉浏览器只允许加载指定源的资源,是非常有效的终极手段。
- 使用 HttpOnly Cookie:防止 JavaScript 读取敏感的 Cookie 信息。
- 避免使用 innerHTML,优先使用 textContent。
什么是CSRF?
CSRF(Cross-Site Request Forgery,跨站请求伪造)是指攻击者诱导用户在已登录的可信网站上执行未授权操作。CSRF 利用的是 浏览器会自动携带 Cookie(或 Token)的特性。攻击者无法直接读取用户的 Cookie,但可以利用浏览器自动带上它。CSRF 攻击流程:
- 用户登录了银行网站 bank.com,浏览器保存了登录 Cookie。
- 然后用户访问了攻击者的网站。
- 攻击者的网站偷偷发送了一个请求,此时浏览器自动带上 bank.com 的 Cookie。
- 银行服务器以为这是用户发的请求,于是执行了转账操作!
CSRF 攻击的几种常见方式:
- 图片 / 脚本标签伪造 GET 请求:浏览器访问图片时自动发送请求。
- 自动提交隐藏表单(POST 请求):利用form元素自动提交表单。
- 通过 AJAX + CORS 绕过限制:攻击者页面用 JavaScript 发请求,只要目标服务允许跨域携带凭证(Access-Control-Allow-Credentials: true),仍然可能被利用。
防御 CSRF 的核心策略:
- 使用 CSRF Token(最常用):每次请求都附带一个随机 Token,服务器验证。
- 使用 SameSite Cookie(现代防御):SameSite 属性可以设置为 Strict、Lax 或 None,用于限制 Cookie 只能在特定情况下发送。
- Strict:任何跨站请求都不会带 Cookie
- Lax:部分跨站请求(如 GET 请求)会带 Cookie,但 POST 请求不会。
- None:所有请求都可以发送 Cookie,但需要服务器设置 Secure 属性,且只能通过 HTTPS 发送。
- 验证请求来源(Referer / Origin Header):服务端可以根据Referer和Origin Header是否请求来源一致,来判断请求是否合法。这种请求可能存在误差,有些请求头可能被浏览器或代理删除。
- 双重 Cookie 验证:服务端发送一个 csrfToken Cookie,前端发送请求时,将 Cookie 值放入请求头,服务端再次验证是否一致。
- 限制敏感操作为 POST + 校验内容类型:不要允许 GET 请求执行修改操作,对 POST 请求,要求
Content-Type: application/json。
