计算机网络之 HTTP 协议

发布于 2024-01-29 14:48:41 字数 4419 浏览 26 评论 0

HTTP 的全称是 HyperText Transfer Protocol,中文是超文本传输协议。它是一个应用层协议,底层使用 TCP 协议来传输,这就是说,在使用 HTTP 发起请求前,需要先建立 TCP 链接,也就是三次握手,然后才能传输数据。

HTTP 的发展历程

HTTP/0.9 & HTTP/1.0

0.9 版本发布于 1991 年,1.0 版本发布于 1996 年。这两个版本就是简单的 request-response 模式,其中 0.9 版本只支持 GET 方法,后来 1.0 版本进行了一些扩展,增加了:

  • 请求行中增加了版本号,如 GET 200 /index.html HTTP/1.1
  • 增加了 HEAD, POST 等方法
  • 增加了响应状态码
  • 引入了 header 头部概念
  • 传输数据不再仅限文本,Content-Type 可以传输其它文件了

HTTP1.0 可以说是比较书面意义的一份规范,让 HTTP 更加规范化了,但是这个版本有个很大问题,每请求一次资源都要新建 TCP 连接,而且是串行请求。

HTTP/1.1

HTTP/1.1 发布于 1999 年,在 1.0 的基础上,解决了一些网络性能问题,另外增加了新特性:

  • 持久链接:通过设置 keep-alive 来重用 TCP 连接
  • 支持 pipeline 网络传输,第一个请求发出了,可以接着发第二个请求出去
  • 增加了 Cache-Control 缓存控制
  • 协议头注增加了 Language, Encoding, Type 等
  • 数据分块传输,这是因为如果页面内容是动态生成的,浏览器不知道何时才能接收完毕,于是服务器将数据分割成多个 chunk,每次发送时附上上次数据块的长度,最后通过发送零长度的块作为数据发送完毕的标志
  • 强制要求 host 头,以便让服务器知道要请求哪个网站,因为存在多个域名解析到同一个 ip 上,要区分具体域名
  • 增加了 PUT、DELETE、OPTIONS 等方法,其中 OPTIONS 常用于 CORS
  • 引入了客户端 cookie

HTTP/2

了解 HTTP/2 之前,先看 HTTP/1.1 还有哪些缺点:

  • HTTP/1.1 还是存在性能问题,虽然可以重用 TCP 链接了,但是请求还是串行发的,需要保证接收顺序
  • HTTP/1.1 传输数据还是以文本的方式,传输成本较高
  • HTTP/1.1 pipeline 时,如果有一个请求 block 了,那队列后的请求也统统被阻塞住了,这就是队头阻塞问题

所以在 2010 年的时候,Google 就在搞一个实验型的协议:SPDY。这个协议后来成为了 HTTP/2 的基础,HTTP/2 发布于 2015 年,它带来了许多新的特性:

  • 采用二进制编码,利于提高传输效率
  • 多路复用,可以在一个 TCP 链接中并发多个 HTTP 请求,解决了 1.1 的串行请求问题。具体就是通过帧和流
  • 压缩请求头,采用 HPACK 算法。两端都维护一个动态的字典表来分析请求头中哪些是重复的
  • 服务端 push 技术,主动推送一些用得到的内容放在客户端缓存里
  • 安全性提升,加密通信要求 TLS 至少是 1.2 版本

以下是 HTTP/2 与 HTTP/1.1 的对比:

HTTP/3

黑客的世界就是不断的折腾,HTTP/2 看起来已经完美了,但还是存在问题:多个 HTTP 请求在复用一个 TCP 链接,如果发生丢包,那所有的 HTTP 请求都必须等待这个被丢了的包重传回来,这还是存在队头阻塞问题,只不过现在是 TCP 的问题。

那既然 TCP 有问题,就干脆放弃掉它!所以 Google 另起炉灶搞了个 QUIC,它抛弃了 HTTP 底层的 TCP,改用 UDP。后台这个协议又又成为了 HTTP/3 的基础。HTTP/3 发布于 2018 年,它的特性如下:

  • 使用 UDP 协议作为底层,自然解决了 HTTP/2 的阻塞问题
  • 在 UDP 的基础上,又加入了 TCP 的丢包重传和拥塞控制功能
  • 换成 UDP 后,直接把 TCP 的三次握手和 TLS 的三次握手合并了,原先是六次网络交互,现在只需三次

可以说,HTTP/3 是在 UDP 上组合了 TCP + TLS + HTTP/2 的功能,由于动了底层协议,它离大规模应用还很遥远。

HTTP 请求的结构

HTTP 是基于客户端-服务器模型的,客户端发送请求,服务端响应请求。请求和响应都由以下部分组成:

  • 请求行/响应行
  • 头部(Header)
  • 主体内容(Body)

请求行

包含请求方法、状态码、路径和版本,如 GET 200 /index.html HTTP/1.1
请求方法包含:

  • GET
  • POST
  • HEAD
  • PUT
  • DELETE
  • OPTIONS
  • CONNECT
  • TRACE

其中 GetPost 的区别有:

  • 从缓存的角度,get 可以被缓存,post 不会
  • 从编码角度,get 只能进行 url 编码,接收 ASCII 字符;post 没有限制
  • 从参数角度,get 请求参数在 url 中;而 post 则是放在 body 里
  • 从幂等性角度,get 是幂等的,post 是不幂等
  • 从 TCP 角度,get 会一次性把请求报文发送出去;而 post 则会分为两个 TCP 包,先发送 header 部分,如果服务器响应 100;再继续发送 body 部分

状态码主要有 1xx2xx3xx4xx5xx 几种
1 xx:请求接收,继续处理

  • 100:请求已被接收,可以继续发送
  • 101:从 HTTP 升级为 websocket ,如果服务器同意变更,返回 101
  • 103:客户端应该在服务器返回 HTML 前开始预加载资源

2xx:成功

  • 200:请求成功
  • 204:与 200 一样,但响应没有 body
  • 206:返回部分内容,它的使用场景是分块,断点续传(content-range)

3xx:重定向相关

  • 301:永久重定向,比如域名换了
  • 302:临时重定向
  • 304:资源未修改,可使用协商缓存
  • 307:临时重定向,与 302 区别在于不允许将原本为 POST 的请求重定向到 GET 请求上

4xx: 客户端错误

  • 401:未进行身份认证
  • 403:无权限,禁止访问
  • 404:资源不存在
  • 405:请求方法不被允许

5xx: 服务器错误

  • 500:服务器错误
  • 502:网关或代理出现错误
  • 503:服务不可达
  • 504:网关超时

请求头

包含 request header 和 response header。这里列举几个常见的头部字段:

  • Content-Type
  • Content-Length
  • User-Agent
  • Host
  • accept
  • accept-encoding
  • cookie

请求 body

常见 body 格式:

  • application/json
  • application/x-www-form-urlencoded
  • multipart/form-data 文件上传
  • text/xml

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

掩耳倾听

暂无简介

文章
评论
27 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文