Skip to content

HTTP

导航目录

HTTP 协议特点

功能说明:HTTP 协议的核心特性,决定了其在 Web 通信中的行为。

  • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有 GETHEADPOST。每种方法规定了客户与服务器联系的类型不同。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
  • 灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。
  • 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  • 无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
  • 支持 B/S 及 C/S 模式:适用于浏览器-服务器和客户端-服务器架构。

HTTP 报文的组成部分

功能说明:HTTP 报文是 HTTP 协议中客户端与服务器之间传递数据的格式。

请求报文组成

  1. 请求行:用来说明请求类型、要访问的资源以及所使用的 HTTP 版本。

    GET /hu.jpg HTTP/1.1

    GET 说明请求类型为 GET,/hu.jpg 为要访问的资源,该行的最后一部分说明使用的是 HTTP 1.1 版本。

  2. 请求头部:紧接着请求行之后的部分,用来说明服务器要使用的附加信息。

    HOST: example.com
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36

    HOST 将指出请求的目的地。User-Agent 是浏览器类型检测逻辑的重要基础,由浏览器定义并在每个请求中自动发送。

  3. 空行:请求头部后面的空行是必须的。

    即使第四部分的请求数据为空,也必须有空行。

  4. 请求数据:也叫主体,可以添加任意的其他数据。

    这个例子的请求数据为空。

HTTP 状态码

功能说明:HTTP 状态码是服务器对客户端请求的响应状态的数字代码,用于表示请求的处理结果。

状态码分类

  • 1xx:指示信息 -- 表示请求已接收,继续处理
  • 2xx:成功 -- 表示请求已被成功接收、理解、接受
  • 3xx:重定向 -- 要完成请求必须进行更进一步的操作
  • 4xx:客户端错误 -- 请求有语法错误或请求无法实现
  • 5xx:服务器端错误 -- 服务器未能实现合法的请求

常见状态码

  • 200 OK:客户端请求成功
  • 201 Created:已创建
  • 202 Accepted:已接受
  • 203 Non-Authoritative Information:非授权信息
  • 204 No Content:成功,无内容
  • 205 Reset Content:成功,重置内容
  • 206 Partial Content:成功,部分内容(断点续传)
  • 301 Moved Permanently:永久移动,重定向
  • 302 Found:临时移动,可使用原有 URI
  • 304 Not Modified:资源未修改,可使用缓存
  • 305 Use Proxy:需代理访问
  • 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
  • 401 Unauthorized:请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用
  • 403 Forbidden:服务器收到请求,但是拒绝提供服务
  • 404 Not Found:请求资源不存在,例如输入了错误的 URL
  • 500 Internal Server Error:服务器发生不可预期的错误
  • 503 Service Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常

GET、POST 区别

功能说明:GET 和 POST 是 HTTP 协议中最常用的两种请求方法,它们在使用场景和行为上有明显区别。

  • 缓存:GET 请求会被浏览器主动缓存,POST 不会,除非手动设置
  • 参数限制:GET 请求参数在 URL 中是会限制的,POST 没有限制
  • 参数位置:GET 请求参数在 URL 中,POST 放在 request body 中
  • 安全性:GET 请求参数暴露在 URL 中,POST 请求参数在请求体中,相对更安全
  • 幂等性:GET 请求是幂等的(多次请求结果相同),POST 请求是非幂等的(多次请求可能产生不同结果)

长连接与短连接

功能说明:长连接和短连接是 HTTP 协议中两种不同的连接管理方式,影响着客户端与服务器之间的通信效率。

  • 短连接:在 HTTP/1.0 中默认使用。客户端和服务器每进行一次 HTTP 操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个 HTML 或其他类型的 Web 页中包含有其他的 Web 资源(如 JavaScript 文件、图像文件、CSS 文件等),每遇到这样一个 Web 资源,浏览器就会重新建立一个 HTTP 会话。

  • 长连接:从 HTTP/1.1 起,默认使用长连接,用以保持连接特性。使用长连接的 HTTP 协议,会在响应头加入这行代码:Connection: keep-alive

    在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如 Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

  • 本质:HTTP 协议的长连接和短连接,实质上是 TCP 协议的长连接和短连接。

HTTP 缓存架构图

httpcache

Last-Modified & ETag

功能说明:Last-Modified 和 ETag 是 HTTP 协议中用于缓存验证的两种机制,用于判断资源是否发生变化。

基本概念

  • Last-Modified:文件最后修改的时间
  • ETag:服务端对文件的索引节、大小和最后修改时间进行 Hash 后得到的值

为什么需要 ETag?

  1. 时间精度问题:如果在一秒钟之内对一个文件进行两次更改,Last-Modified 可能就会不正确
  2. 服务器限制:某些服务器不能精确的得到文件的最后修改时间
  3. 内容未变:一些文件也许会周期性的更改,但是内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新 GET

为什么需要 Last-Modified?

  • 性能优化:对于一些图片等静态文件的修改,如果每次扫描内容生成 ETag 来比较,显然要比直接比较修改时间慢很多
  • 互补性:两种判断机制相辅相成,共同提高缓存验证的准确性

强缓存与协商缓存

功能说明:HTTP 缓存机制分为强缓存和协商缓存两种,用于减少网络请求,提高页面加载速度。

强缓存

强缓存时间未过期不会主动向服务器发请求,浏览器直接从本地缓存读取资源。

  • Cache-Control
    • max-age:浏览器缓存时间,时间未过期直接读取浏览器缓存
    • s-max-age:CDN 缓存时间,s-max-age 大于 max-age,优先读取 CDN
    • private:私有的缓存一般存在浏览器
    • public:公共的缓存一般存在 CDN 服务器
    • no-store:禁用缓存
  • Expires:缓存过期时间,max-age 优先级高于 Expires

协商缓存

当强缓存过期后,浏览器会向服务器发送请求,验证资源是否发生变化。

  • Last-Modified / If-Modified-Since

    • Last-Modified:服务器资源最后一次修改的时间,存在 response
    • If-Modified-Since:浏览器请求时会带上 If-Modified-Since 时间,服务器对比时间相同返回 304 读取浏览器缓存,不同返回 200 重新请求资源
  • ETag / If-None-Match

    • ETag:服务端生成的资源唯一标识,存在 response
    • If-None-Match:浏览器请求时会带上 If-None-Match 值,服务器对比相同返回 304 读取浏览器缓存,不同返回 200 重新请求资源

优先级

  • 强缓存 > 协商缓存
  • Cache-Control > Expires
  • ETag > Last-Modified

刷新操作对缓存的影响

功能说明:不同的刷新操作会对浏览器缓存产生不同的影响,导致资源加载方式的变化。

  • 正常操作:强制缓存有效,协商缓存有效
  • 手动刷新(浏览器上的刷新):强制缓存失效,协商缓存有效
  • 强制刷新(Ctrl + F5):强制缓存失效,协商缓存失效

HTTP 2.0 的优势

功能说明:HTTP 2.0 是 HTTP 协议的重大升级,带来了显著的性能提升和新特性。

  • 二进制格式传输:采用二进制格式传输数据,而非 HTTP 1.1 的文本格式,二进制格式在协议的解析和优化扩展上带来更多的优势和可能
  • 头部压缩:对消息头采用HPACK 进行压缩传输,能够节省消息头占用的网络流量,而 HTTP 1.1 每次请求都会携带大量冗余头信息,浪费了很多带宽资源
  • 多路复用:多个请求通过一个 TCP 连接并发完成,HTTP 1.1 虽然通过 pipeline 也能并发请求,但是多个请求之间的响应会被阻塞,所以 pipeline 至今也没有被普及应用,而 HTTP 2.0 做到了真正的并发请求,同时,流还支持优先级和流量控制
  • Server Push:服务端能够更快的把资源推送给客户端,例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 再发送这些请求,当客户端需要的时候,它已经在客户端了

同源策略

功能说明:同源策略是浏览器的一种安全机制,限制了来自不同源的文档或脚本对当前文档的访问能力。

  • 同源的定义协议相同域名相同端口相同

例如:https://example.com:8080https://example.com:8080 是同源,而 http://example.comhttps://www.example.comhttps://example.com:8081 都不是同源

跨域请求限制

功能说明:由于同源策略的存在,浏览器对跨域请求施加了一系列限制,以保护用户安全。

TIP

跨域是浏览器的限制,和服务端无关

  • Cookie、localStorage 等存储无法读取
  • DOM 无法操作
  • Ajax 不能发送:Ajax 只能在同源下使用

不受同源策略限制的情况

功能说明:虽然浏览器有同源策略限制,但有一些技术和方法可以绕过这些限制,实现跨域通信。

  • WebSocket:不受同源策略的限制,可直接与不同源的服务器建立连接
  • window.postMessage:HTML5 中新引进的方法,可用于跨域传送数据
  • CORS:服务器设置 Access-Control-Allow-Origin 头部,允许跨域请求
  • JSONP:利用 script 标签不受跨域限制的特性,让服务器端返回可执行的回调函数,从而获取数据

跨域请求

功能说明:跨域请求是指从一个源向另一个源发送的 HTTP 请求,需要遵循浏览器的跨域策略。

  • 预检机制:跨域如果是复杂请求会有一个OPTIONS 预检机制,预检通过成功后才会发送真正的请求
  • 简单请求:GET、POST 等基本请求方法,且头部信息不包含自定义字段
  • 复杂请求:除简单请求外的其他请求,或添加了自定义头部信息的请求
  • Cookie 限制:默认情况下,cookie 不允许跨域传递

跨域预检请求优化

功能说明:OPTIONS 预检请求可能会导致请求变慢,需要采取措施进行优化。

TIP

OPTIONS(预检/嗅探请求)可能会导致请求变慢,每次进行接口请求时,浏览器会先发出一个 OPTIONS 请求,然后才发起正式的请求。

优化方法

通过设置响应头部的 Access-Control-Max-Age 来设置预检请求有效期,即在设置的时间内只有第一次会发送预检请求,下次相同接口的请求(相同接口 & 相同参数)不会再发出预检请求,而是直接发送真实请求。

nginx
location /api/ {
  add_header "Access-Control-Max-Age" 600;
  proxy_pass http://a**********/;
}

这样可以有效减少 OPTIONS 请求的次数,提高跨域请求的性能

HTTP 对比 HTTPS

  • HTTP 是明文传输,敏感信息容易被中间劫持
  • HTTPS = HTTP + SSL/TLS 非对称加密,劫持了也无法解密

对称加密

功能说明:对称加密是一种加密方式,使用同一个密钥进行加密和解密。

  • 原理:加解密都是用的同一个 key
  • 特点:加密速度快,但密钥管理困难,需要安全的密钥传输渠道

非对称加密

功能说明:非对称加密是一种加密方式,使用一对密钥(公钥和私钥)进行加密和解密。

  • 密钥对:会生成一对 公钥 (Public Key)私钥 (Private Key)
  • 加密解密:用 公钥 进行加密,私钥 解密
  • 签名验证:用 私钥 签名,公钥 验证
  • 安全性:私钥不会对外公开,相对安全指数高

HTTP 2 的多路复用

功能说明:HTTP 2 的多路复用是一项重要的性能优化技术,解决了 HTTP 1.x 中的队头阻塞问题。

HTTP 1.x 的问题

在 HTTP/1 中,每次请求都会建立一次 HTTP 连接,也就是我们常说的 3 次握手 4 次挥手,这个过程在一次请求过程中占用了相当长的时间,即使开启了 Keep-Alive ,解决了多次连接的问题,但是依然有两个效率上的问题:

  1. 串行的文件传输:当请求 a 文件时,b 文件只能等待,等待 a 连接到服务器、服务器处理文件、服务器返回文件,这三个步骤。我们假设这三步用时都是 1 秒,那么 a 文件用时为 3 秒,b 文件传输完成用时为 6 秒,依此类推。(注:此项计算有一个前提条件,就是浏览器和服务器是单通道传输)

  2. 连接数过多:我们假设 Apache 设置了最大并发数为 300,因为浏览器限制,浏览器发起的最大请求数为 6,也就是服务器能承载的最高并发为 50,当第 51 个人访问时,就需要等待前面某个请求处理完成。

HTTP 2 的解决方案

HTTP/2 的多路复用就是为了解决上述的两个性能问题。在 HTTP/2 中,有两个非常重要的概念:

  • 帧(frame):代表着最小的数据单位,每个帧会标识出该帧属于哪个流
  • 流(stream):多个帧组成的数据流

多路复用:在一个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免 HTTP 旧版本中的队头阻塞问题,极大的提高传输性能。

HTTPS 中间人攻击

功能说明:中间人攻击是一种常见的网络攻击方式,攻击者在客户端和服务器之间拦截和篡改通信数据。

TIP

服务端在发送浏览器的公钥中加入 CA 证书,浏览器可以验证 CA 证书的有效性,从而防止中间人攻击。

攻击过程

  1. 服务器向客户端发送公钥
  2. 攻击者截获公钥,保留在自己手上
  3. 攻击者生成伪造的公钥,发给客户端
  4. 客户端收到伪造的公钥,生成加密 hash 值发给服务器
  5. 攻击者获得加密 hash 值,用自己的私钥解密获得真密钥
  6. 攻击者生成假的加密 hash 值,发给服务器
  7. 服务器用私钥解密获得假密钥
  8. 服务器用假密钥加密传输信息,攻击者可以截获并解密

防护措施

  • 使用 CA 证书:服务端使用由可信 CA 签发的证书,浏览器会验证证书的有效性
  • 证书验证:客户端在收到证书后,会验证证书的签名和有效期
  • HTTPS:使用 HTTPS 协议,确保通信加密

TCP 和 UDP 区别

功能说明:TCP 和 UDP 是两种不同的传输层协议,它们在连接方式、可靠性、传输效率等方面有显著区别。

  • 连接方式:TCP 面向连接(如打电话要先拨号建立连接),UDP 是无连接的,即发送数据之前不需要建立连接
  • 可靠性:TCP 提供可靠的服务,UDP 尽最大努力交付,即不保证可靠交付
  • 实时性:UDP 具有较好的实时性,工作效率比 TCP 高,适用于对高速传输和实时性有较高的通信或广播通信
  • 连接数:每一条 TCP 连接只能是一对一的,UDP 支持一对一,一对多,多对一和多对多的交互通信
  • 首部开销:UDP 分组首部开销小(只有 8 个字节),TCP 首部开销较大(20 字节)
  • 数据传输:TCP 面向字节流,实际上是 TCP 把数据看成一连串无结构的字节流;UDP 是面向报文的,一次交付一个完整的报文,报文不可分割,报文是 UDP 数据报处理的最小单位
  • 应用场景:UDP 适合一次性传输较小数据的网络应用,如 DNS,SNMP 等;TCP 适合需要可靠传输的应用,如 HTTP,FTP 等

为什么有非对称加密,还需要 CA 证书?

功能说明:非对称加密虽然安全,但存在密钥验证的问题,CA 证书可以解决这个问题。

  • 非对称加密的问题:无法证明公开密钥就是接收方公开的那个密钥,而不是被攻击者调包的密钥
  • CA 证书的作用:由数字证书认证机构(CA,Certificate Authority)颁发的公开密钥证书,用于验证公钥的真实性
  • CA 的角色:数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上,相当于公证处,大家都相信公证处,你说你是张三别人不一定信,它说你是张三别人才能百分百信

TCP 连接:三次握手与四次挥手

功能说明:TCP 连接的建立和关闭过程,分别通过三次握手和四次挥手来完成。

三次握手

功能说明:三次握手是 TCP 建立连接的过程,确保客户端和服务器之间的通信链路正常。

过程

  1. 客户端发送 SYN 包,服务端收到。服务端确认:客户端的发送能力是正常的
  2. 服务端发送 SYN+ACK 包,客户端收到。客户端确认:服务端的接收和发送能力是正常的
  3. 客户端发送 ACK 包,服务端收到。服务端确认:客户端的接收能力是正常的,连接建立完成

建立连接完成,然后就开始发送数据,通讯。

四次挥手

功能说明:四次挥手是 TCP 关闭连接的过程,确保双方都已完成数据传输。

过程

  1. 客户端发送 FIN 包,服务端接收。服务端确认:客户端已经请求结束
  2. 服务端发送 ACK 包,客户端接收。客户端确认:服务端已经收到关闭请求,等待服务端关闭
  3. 服务端发送 FIN 包,客户端接收。客户端确认:服务端已经发送完成,可以关闭
  4. 客户端发送 ACK 包,服务端接收。服务端确认:可以关闭了