几分钟带你搞定HTTP的前世今生

简介

HTTP(超文本传输协议),是用于从万维网服务器传输超文本到本地浏览器的传送协议,是互联网上应用最为广泛的一种网络协议,所有的www文件都必须遵守这个标准。

HTTP是一个属于应用层的面向对象的协议,由于其简便、快速的方式,适用于分布式超媒体信息系统。 它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。

HTTP协议版本

大致的版本可以分为以下五个:

  • HTTP/0.9(初始诞生)
  • HTTP/1.0
  • HTTP/1.1
  • HTTP/2
  • HTTP/3

发展的历史如下:

HTTP/0.9

该版本极其简单,起初是为了学术交流,传递html文本,只有一个命令 GET

  1. TCP建立连接
  2. 客户端发GET请求 /index.html
  3. 服务器返回html文件,以ASCII字符流返回
  4. 断开连接

-- 特点:

  1. 只有请求行,没有请求头和请求体
  2. 服务器没有响应头,直接返回数据就可以
  3. 内容都是以ASCII字符流来传输

HTTP/1.0

浏览器的诞生,支持多类型文件的下载 (html, css, js, 图片,音频,视频),于是http就不得不支持不同类型文件的下载

-- 如何实现多种类型文件的下载?

  1. 引入请求头和响应头,key-value
  2. http发请求时会带上请求头信息,服务器返回数据时,会先返回响应头信息

-- 请求头和响应头是如何工作的?

  1. 浏览器要知道服务器返回的类型;
  2. 浏览器要知道服务器返回的数据压缩方式;
  3. 浏览器要知道服务器文件的编码方式;

请求头:

js 复制代码
accept: text/html //类型
accept-encoding: gzip,deflate,br //压缩方式
accept-Charset: ISO-8859-1,utf-8 //编码方式
accept-language: zh-CN,zh-xx //语言

响应头:

js 复制代码
content-encoding: br
content-type: text/html; charset=utf-8

status: 200 //状态码
cache //(缓存)机制
content-length: 901

HTTP/1.1 (缝缝补补)

对于 1.0:

lua 复制代码
建立连接 --- HTTP请求 HTTP响应 --- 断开连接
建立连接 --- HTTP请求 HTTP响应 --- 断开连接
建立连接 --- HTTP请求 HTTP响应 --- 断开连接
···

1.1 时,引入了持久连接建立一个TCP连接,可以进行多个http请求,即:

lua 复制代码
        -- http请求1 http响应1 --
        -- http请求2 http响应2 --
建立连接 -- http请求3 http响应3 --断开连接
        -- http请求4 http响应4 --
        -- http请求5 http响应5 --
        ···

请求头:Connection: close (不启用持久连接)

目前,对于同一个域名,大多数浏览器允许同时建立6个持久连接

其他功能:

  1. 管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。
  2. Content-Length 字段,一个TCP连接现在可以传送多个回应,势必就要有一种机制,区分数据包是属于哪一个回应的。这就是Content-length字段的作用,声明本次回应的数据长度。
yaml 复制代码
Content-Length: 3495

上面代码告诉浏览器,本次回应的长度是3495个字节,后面的字节就属于下一个回应了。

  1. 分块传输编码(chunked transfer encoding), 将数据分割成若干个数据块,每个数据块上标记数据块的长度,最后发送一个空数据块来告诉浏览器数据传输完毕。
makefile 复制代码
Transfer-Encoding: chunked
  1. 客户端请求的头信息新增了Host字段,用来指定服务器的域名。
arduino 复制代码
Host: www.example.com
//有了Host字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础

缺点队头阻塞

虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为'队头阻塞'

这里再简单总结一下:

http/1.1的优化

  • 增加了持久化连接
  • 浏览器可以同时维护6个TCP连接
  • 使用了CDN实现域名分片

主要存在的问题

  1. 对带宽的利用率很低

    -- TCP慢启动

    -- 同时开启多条TCP连接会竞争固定带宽

    -- 队头阻塞问题

HTTP/2

多路复用(解决队头阻塞问题)

  • 一个域名只使用一个TCP的长连接
  • 资源并行请求

二进制协议

HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。

二进制协议的一个好处是,可以定义额外的帧。HTTP/2 定义了近十种帧,为将来的高级应用打好了基础。如果使用文本实现这种功能,解析数据将会变得非常麻烦,二进制解析则方便得多。

可以设置请求的优先级 :优先级越高,服务器就会越早回应

服务器推送 :当服务器给客户端返回一个html后,服务器自己知道该html中需要哪几份js和css,那么服务器就提前准备好这些js和css并且一并将js,css发送给浏览器

头信息压缩压缩 :请求头和响应头

一方面,头信息使用gzipcompress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

2.0的缺陷:

  1. TCP的队头阻塞:因为TCP的传输是有序的,单个数据包丢失会造成阻塞
  2. TCP建立连接的延时:TCP握手,HTTPS中的TLS加密过程也有一次握手

HTTP/3

由于HTTP/2存在的缺陷,那我们能否通过改进TCP协议来优化呢?

改进TCP协议(TCP僵化,实现不可能)

  1. 太多中间设备基于TCP生产,路由器、交换机...
  2. 操作系统内核也是基于TCP来工作的

于是乎HTTP/2存在的问题都是TCP导致的,既然改进TCP协议不现实,那不妨大胆一点,跳出这个禁锢,我们能否不基于TCP传输,使用UDP进行传输呢?所以有了UDP协议的升级。

QUIC协议(UDP升级)

  1. 有多路复用
  2. 传输可靠

HTTP/3面临的挑战

  1. 浏览器和服务器都要升级支持QUIC协议
  2. 系统对UDP的优化很低,对TCP的优化很高
  3. 中间设备僵化

总结

这就是HTTP至今为止的故事,看完本文如果对你有所帮助,记得点赞支持,也可收藏方便随时查看啦,文章可能存在一些错误,欢迎指出,一起讨论共同进步。

相关推荐
ThisIsClark1 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试
唐 城1 小时前
curl 放弃对 Hyper Rust HTTP 后端的支持
开发语言·http·rust
DevilHeart灬2 小时前
使用Grafana中按钮插件实现收发HTTP请求
http·grafana
测试19982 小时前
外包干了2年,技术退步明显....
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
Aphasia3113 小时前
一次搞懂 JS 对象转换,从此告别类型错误!
javascript·面试
GISer_Jing5 小时前
2025年前端面试热门题目——HTML|CSS|Javascript|TS知识
前端·javascript·面试·html
总是学不会.6 小时前
第五篇:前后端如何“扯皮”——HTTP 在开发中的应用
java·网络·网络协议·http·开发
上海运维Q先生6 小时前
面试题整理14----kube-proxy有什么作用
运维·面试·kubernetes
火狮7 小时前
鸿蒙Next API 12开发,使用@ohos/axios进行HTTP请求
http·华为·harmonyos
开发者每周简报7 小时前
求职市场变化
人工智能·面试·职场和发展