当前位置: 首页 > news >正文

浏览器工作原理与实践--HTTP/1:HTTP性能优化

谈及浏览器中的网络,就避不开HTTP。我们知道HTTP是浏览器中最重要且使用最多的协议,是浏览器和服务器之间的通信语言,也是互联网的基石。而随着浏览器的发展,HTTP为了能适应新的形式也在持续进化,我认为学习HTTP的最佳途径就是了解其发展史,所以在接下来的三篇文章中,我会从浏览器发展的视角来和你聊聊HTTP演进。这三篇分别是即将完成使命的HTTP/1、正在向我们走来的HTTP/2,以及未来的HTTP/3。

本文主要介绍的是HTTP/1.1,我们先讲解HTTP/1.1的进化史,然后再介绍在进化过程中所遇到的各种瓶颈,以及对应的解决方法。

超文本传输协议HTTP/0.9

首先我们来看看诞生最早的HTTP/0.9。HTTP/0.9是于1991年提出的,主要用于学术交流,需求很简单——用来在网络之间传递HTML超文本的内容,所以被称为超文本传输协议。整体来看,它的实现也很简单,采用了基于请求响应的模式,从客户端发出请求,服务器返回数据。

下面我们就来看看HTTP/0.9的一个完整的请求流程(可参考下图)。

  • 因为HTTP都是基于TCP协议的,所以客户端先要根据IP地址、端口和服务器建立TCP连接,而建立连接的过程就是TCP协议三次握手的过程。

  • 建立好连接之后,会发送一个GET请求行的信息,如GET /index.html用来获取index.html。

  • 服务器接收请求信息之后,读取对应的HTML文件,并将数据以ASCII字符流返回给客户端。

  • HTML文档传输完成后,断开连接。

HTTP/0.9请求流程

总的来说,当时的需求很简单,就是用来传输体积很小的HTML文件,所以HTTP/0.9的实现有以下三个特点。

  • 第一个是只有一个请求行,并没有HTTP请求头和请求体,因为只需要一个请求行就可以完整表达客户端的需求了。

  • 第二个是服务器也没有返回头信息,这是因为服务器端并不需要告诉客户端太多信息,只需要返回数据就可以了。

  • 第三个是返回的文件内容是以ASCII字符流来传输的,因为都是HTML格式的文件,所以使用ASCII字节码来传输是最合适的。

被浏览器推动的HTTP/1.0

HTTP/0.9虽然简单,但是已经可以满足当时的需求了。不过变化是这个世界永恒不变的主旋律,1994年底出现了拨号上网服务,同年网景又推出一款浏览器,从此万维网就不局限于学术交流了,而是进入了高速的发展阶段。随之而来的是万维网联盟(W3C)和HTTP工作组(HTTP-WG)的创建,它们致力于HTML的发展和HTTP的改进。

万维网的高速发展带来了很多新的需求,而HTTP/0.9已经不能适用新兴网络的发展,所以这时就需要一个新的协议来支撑新兴网络,这就是HTTP/1.0诞生的原因。不过在详细分析HTTP/1.0之前,我们先来分析下新兴网络都带来了哪些新需求。

首先在浏览器中展示的不单是HTML文件了,还包括了JavaScript、CSS、图片、音频、视频等不同类型的文件。因此支持多种类型的文件下载是HTTP/1.0的一个核心诉求,而且文件格式不仅仅局限于ASCII编码,还有很多其他类型编码的文件。

那么该如何实现多种类型文件的下载呢?

文章开头我们说过,HTTP是浏览器和服务器之间的通信语言,不过HTTP/0.9在建立好连接之后,只会发送类似GET /index.html的简单请求命令,并没有其他途径告诉服务器更多的信息,如文件编码、文件类型等。同样,服务器是直接返回数据给浏览器的,也没有其他途径告诉浏览器更多的关于服务器返回的文件信息。

这种简单的交流型形式无疑不能满足传输多种类型文件的需求,那为了让客户端和服务器能更深入地交流,HTTP/1.0引入了请求头和响应头,它们都是以为Key-Value形式保存的,在HTTP发送请求时,会带上请求头信息,服务器返回数据时,会先返回响应头信息。至于HTTP/1.0具体的请求流程,你可以参考下图。

HTTP/1.0的请求流程

有了请求头和响应头,浏览器和服务器就能进行更加深入的交流了。

那HTTP/1.0是怎么通过请求头和响应头来支持多种不同类型的数据呢?

要支持多种类型的文件,我们就需要解决以下几个问题。

  • 首先,浏览器需要知道服务器返回的数据是什么类型的,然后浏览器才能根据不同的数据类型做针对性的处理。

  • 其次,由于万维网所支持的应用变得越来越广,所以单个文件的数据量也变得越来越大。为了减轻传输性能,服务器会对数据进行压缩后再传输,所以浏览器需要知道服务器压缩的方法。

  • 再次,由于万维网是支持全球范围的,所以需要提供国际化的支持,服务器需要对不同的地区提供不同的语言版本,这就需要浏览器告诉服务器它想要什么语言版本的页面。

  • 最后,由于增加了各种不同类型的文件,而每种文件的编码形式又可能不一样,为了能够准确地读取文件,浏览器需要知道文件的编码类型。

基于以上问题,HTTP/1.0的方案是通过请求头和响应头来进行协商,在发起请求时候会通过HTTP请求头告诉服务器它期待服务器返回什么类型的文件、采取什么形式的压缩、提供什么语言的文件以及文件的具体编码。最终发送出来的请求头内容如下:

accept: text/html
accept-encoding: gzip, deflate, br
accept-Charset: ISO-8859-1,utf-8
accept-language: zh-CN,zh

其中第一行表示期望服务器返回html类型的文件,第二行表示期望服务器可以采用gzip、deflate或者br其中的一种压缩方式,第三行表示期望返回的文件编码是UTF-8或者ISO-8859-1,第四行是表示期望页面的优先语言是中文。

服务器接收到浏览器发送过来的请求头信息之后,会根据请求头的信息来准备响应数据。不过有时候会有一些意外情况发生,比如浏览器请求的压缩类型是gzip,但是服务器不支持gzip,只支持br压缩,那么它会通过响应头中的content-encoding字段告诉浏览器最终的压缩类型,也就是说最终浏览器需要根据响应头的信息来处理数据。下面是一段响应头的数据信息:

content-encoding: br
content-type: text/html; charset=UTF-8

其中第一行表示服务器采用了br的压缩方法,第二行表示服务器返回的是html文件,并且该文件的编码类型是UTF-8。

有了响应头的信息,浏览器就会使用br方法来解压文件,再按照UTF-8的编码格式来处理原始文件,最后按照HTML的方式来解析该文件。这就是HTTP/1.0支持多文件的一个基本的处理流程。

HTTP/1.0除了对多文件提供良好的支持外,还依据当时实际的需求引入了很多其他的特性,这些特性都是通过请求头和响应头来实现的。下面我们来看看新增的几个典型的特性:

  • 有的请求服务器可能无法处理,或者处理出错,这时候就需要告诉浏览器服务器最终处理该请求的情况,这就引入了状态码。状态码是通过响应行的方式来通知浏览器的。

  • 为了减轻服务器的压力,在HTTP/1.0中提供了Cache机制,用来缓存已经下载过的数据。

  • 服务器需要统计客户端的基础信息,比如Windows和macOS的用户数量分别是多少,所以HTTP/1.0的请求头中还加入了用户代理的字段。

缝缝补补的HTTP/1.1

不过随着技术的继续发展,需求也在不断迭代更新,很快HTTP/1.0也不能满足需求了,所以HTTP/1.1又在HTTP/1.0的基础之上做了大量的更新。接下来我们来看看HTTP/1.0遇到了哪些主要的问题,以及HTTP/1.1又是如何改进的。

1. 改进持久连接

HTTP/1.0每进行一次HTTP通信,都需要经历建立TCP连接、传输HTTP数据和断开TCP连接三个阶段(如下图)。

HTTP/1.0的短连接

在当时,由于通信的文件比较小,而且每个页面的引用也不多,所以这种传输形式没什么大问题。但是随着浏览器普及,单个页面中的图片文件越来越多,有时候一个页面可能包含了几百个外部引用的资源文件,如果在下载每个文件的时候,都需要经历建立TCP连接、传输数据和断开连接这样的步骤,无疑会增加大量无谓的开销。

为了解决这个问题,HTTP/1.1中增加了持久连接的方法,它的特点是在一个TCP连接上可以传输多个HTTP请求,只要浏览器或者服务器没有明确断开连接,那么该TCP连接会一直保持。

HTTP/1.0的持久连接

从上图可以看出,HTTP的持久连接可以有效减少TCP建立连接和断开连接的次数,这样的好处是减少了服务器额外的负担,并提升整体HTTP的请求时长。

持久连接在HTTP/1.1中是默认开启的,所以你不需要专门为了持久连接去HTTP请求头设置信息,如果你不想要采用持久连接,可以在HTTP请求头中加上Connection: close。目前浏览器中对于同一个域名,默认允许同时建立6个TCP持久连接。

2. 不成熟的HTTP管线化

持久连接虽然能减少TCP的建立和断开次数,但是它需要等待前面的请求返回之后,才能进行下一次请求。如果TCP通道中的某个请求因为某些原因没有及时返回,那么就会阻塞后面的所有请求,这就是著名的队头阻塞的问题。

HTTP/1.1中试图通过管线化的技术来解决队头阻塞的问题。HTTP/1.1中的管线化是指将多个HTTP请求整批提交给服务器的技术,虽然可以整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器的请求。

FireFox、Chrome都做过管线化的试验,但是由于各种原因,它们最终都放弃了管线化技术。

3. 提供虚拟主机的支持

在HTTP/1.0中,每个域名绑定了一个唯一的IP地址,因此一个服务器只能支持一个域名。但是随着虚拟主机技术的发展,需要实现在一台物理主机上绑定多个虚拟主机,每个虚拟主机都有自己的单独的域名,这些单独的域名都公用同一个IP地址。

因此,HTTP/1.1的请求头中增加了Host字段,用来表示当前的域名地址,这样服务器就可以根据不同的Host值做不同的处理。

4. 对动态生成的内容提供了完美支持

在设计HTTP/1.0时,需要在响应头中设置完整的数据大小,如Content-Length: 901,这样浏览器就可以根据设置的数据大小来接收数据。不过随着服务器端的技术发展,很多页面的内容都是动态生成的,因此在传输数据之前并不知道最终的数据大小,这就导致了浏览器不知道何时会接收完所有的文件数据。

HTTP/1.1通过引入Chunk transfer机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。这样就提供了对动态内容的支持。

5. 客户端Cookie、安全机制

除此之外,HTTP/1.1还引入了客户端Cookie机制和安全机制。其中,Cookie机制我们在《03 | HTTP请求流程:为什么很多站点第二次打开速度会很快?》这篇文章中介绍过了,而安全机制我们会在后面的安全模块中再做介绍,这里就不赘述了。

总结

好了,今天就介绍到这里,下面我来总结下本文的主要内容。

本文我们重点强调了HTTP是浏览器和服务器的通信语言,然后我们从需求演变的角度追溯了HTTP的发展史,在诞生之初的HTTP/0.9因为需求简单,所以和服务器之间的通信过程也相对简单。

由于万维网的快速崛起,带来了大量新的需求,其中最核心的一个就是需要支持多种类型的文件下载, 为此HTTP/1.0中引入了请求头和响应头。在支持多种类型文件下载的基础之上,HTTP/1.0还提供了Cache机制、用户代理、状态码等一些基础信息。

但随着技术和需求的发展,人们对文件传输的速度要求越来越高,故又基于HTTP/1.0推出了HTTP/1.1,增加了持久连接方法来提升连接效率,同时还尝试使用管线化技术提升效率(不过由于各种原因,管线化技术最终被各大厂商放弃了)。除此之外,HTTP/1.1还引入了Cookie、虚拟主机的支持、对动态内容的支持等特性。

虽然HTTP/1.1在HTTP/1.0的基础之上做了大量的优化,但是由于一些效率问题始终很难解决,所以最终还是被HTTP/2所取代,这就是我们下一篇文章要介绍的内容了。

相关文章:

浏览器工作原理与实践--HTTP/1:HTTP性能优化

谈及浏览器中的网络,就避不开HTTP。我们知道HTTP是浏览器中最重要且使用最多的协议,是浏览器和服务器之间的通信语言,也是互联网的基石。而随着浏览器的发展,HTTP为了能适应新的形式也在持续进化,我认为学习HTTP的最佳…...

idea 使用springboot helper 创建springboot项目

Spring Boot Helper 是一个在 IntelliJ IDEA 中用于快速创建 Spring Boot 项目的插件。通过这个插件,开发者可以简化 Spring Boot 项目的创建过程,并快速生成所需的依赖和配置文件。以下是使用 Spring Boot Helper 插件创建 Spring Boot 项目的详细步骤&…...

关于 Amazon DynamoDB 的学习和使用

文章主要针对于博主自己的技术栈,从Unity的角度出发,对于 DynamoDB 的使用。 绿色通道: WS SDK for .NET Version 3 API Reference - AmazonDynamoDBClient Amazon DynamoDB Amazon DynamoDB is a fast, highly scalable, highly available,…...

【fastapi】搭建第一个fastapi后端项目

本篇文章介绍一下fastapi后端项目的搭建。其实没有什么好说的,按照官方教程来即可:https://fastapi.tiangolo.com/zh/ 安装依赖 这也是我觉得python项目的槽点之一。所有依赖都安装在本地,一旦在别人电脑上编写项目就又要安装一遍。很扯淡。…...

Qt/QML编程之路:图片进度条的实现(50)

要实现进度条,而进度条是通过一个图片来展示的,比如逐渐增大的音量,或者逐步增大的车速,通过图片显示的效果肯定更好一些。最直接的想法是通过一个透明的rectagle,把不想让看到的遮住,实际上这种方法不可行。 import QtQuick 2.5 import QtQuick.Window 2.2 import QtGra…...

OOCT WPF_D3D项目报错无法加载依赖项

运行示例项目报错缺少dll,发现运用了这个大老李,通过添加PATH路径也无法解决,看到debug文件夹下面没有其他的依赖项。 通过depneds工具可以看到 OCCTProxy_D3D.dll 缺少依赖项,图中的缺项都是OCCT生成的模块dll所以讲这些dll从..…...

模板方法模式:定义算法骨架的设计策略

在软件开发中,模板方法模式是一种行为型设计模式,它在父类中定义一个操作的算法框架,允许子类在不改变算法结构的情况下重定义算法的某些步骤。这种模式是基于继承的基本原则,通过抽象类达到代码复用的目的。本文将详细介绍模板方…...

es6对于变量的解构赋值(数组解构,对象解构,字符串解构,函数解构等)解析(2024-04-12)

1、数组的解构赋值 [ ] 1.1 数组解构的基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。本质上叫模型匹配,等号两边的模型相同就可以对应上。 //以前…...

Flutter学习13 - Widget

1、Flutter中常用 Widget 2、StatelessWidget 和 StateFulWidget Flutter 中的 widget 有很多,但主要分两种: StatelessWidget无状态的 widget如果一个 widget 是最终的或不可变的,那么它就是无状态的StatefulWidget有状态的 widget如果一个…...

Django开发一个学生选课系统

在这个选课系统中,分为管理员和学生两种角色。 学生登录系统以后,只能看到选课信息。管理员登录以后,可以看到选课信息和其他的管理系统。 选课界面如下: 学生管理界面如下: 数据分析界面如下: 数据…...

Vue3项目搭建及文件结构

一. Vue3项目搭建 # 安装Vue CLI npm install -g vue/cli# 通过Vue CLI创建项目: vue create my-vue3-project# 当问到你想要使用哪个版本的Vue时,选择Vue3 # 完成配置后,CLI会自动安装依赖并创建项目 # 最后,启动你的Vue3项目cd…...

【机器学习】Logistic与Softmax回归详解

在深入探讨机器学习的核心概念之前,我们首先需要理解机器学习在当今世界的作用。机器学习,作为人工智能的一个重要分支,已经渗透到我们生活的方方面面,从智能推荐系统到自动驾驶汽车,再到医学影像的分析。它能够从大量…...

MATLAB Simulink仿真搭建及代码生成技术—01自定义新建模型模板

MATLAB Simulink仿真搭建及代码生成技术 目录 01-自定义新建模型模板点击运行:显示效果:查看模型设置: 01-自定义新建模型模板 新建模型代码如下: function new_model(modelname) %建立一个名为SmartAss的新的模型并打开 open_…...

【Java8新特性】二、函数式接口

这里写自定义目录标题 一、什么是函数式接口二、自定义函数式接口三、作为参数传递 Lambda 表达式四、四大内置核心函数式接口1、消费形接口2、供给形接口3、函数型接口4、断言形接口 一、什么是函数式接口 只包含一个抽象方法的接口,称为函数式接口。你可以通过 L…...

供应RTC5606H 芯片现货

长期供应各品牌芯片现货: NVP2443I NVP6324 RTC5606H NZ3802-A IRF100B201 IMX290LQR-G STM32F103C8T6TR STM32F103C8T6TR STM32F103CBT7TR TPS3823-33DBVR IMX326 TPS3823-33DBVR LPC55S69**D100 OCP2184QAD DT3001S23E1-30 EMP8734-33…...

洛谷-P1596 [USACO10OCT] Lake Counting S

P1596 [USACO10OCT] Lake Counting S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using namespace std; const int N110; int m,n; char g[N][N]; bool st[N][N]; //走/没走 int dx[] {-1,-1,-1,0,0,1,1,1}; //八联通 int dy[] {-1,0,1,1,-1,1…...

基于双向长短期神经网络BILSTM的发生概率预测,基于GRU神经网络的发生概率预

目录 背影 摘要 LSTM的基本定义 LSTM实现的步骤 BILSTM神经网络 基于双向长短期神经网络BILSTM的发生概率预测,基于GRU神经网络的发生概率预 完整代码:基于双向长短期神经网络BILSTM的发生概率预测,基于GRU神经网络的发生概率预测资源-CSDN文库 https://download.csdn.net/d…...

对OceanBase中的配置项与系统变量,合法性检查实践

在“OceanBase 配置项&系统变量实现及应用详解”的系列文章中&#xff0c;我们已经对配置项和系统变量的源码进行了解析。当涉及到新增配置项或系统变量时&#xff0c;通常会为其指定一个明确的取值范围或定义一个专门的合法性检查函数。本文将详细阐述在不同情境下&#x…...

YOLOv8绝缘子边缘破损检测系统(可以从图片、视频和摄像头三种方式检测)

可检测图片和视频当中出现的绝缘子和绝缘子边缘是否出现破损&#xff0c;以及自动开启摄像头&#xff0c;进行绝缘子检测。基于最新的YOLO-v8训练的绝缘子检测模型和完整的python代码以及绝缘子的训练数据&#xff0c;下载后即可运行。&#xff08;效果视频&#xff1a;YOLOv8绝…...

【vim 学习系列文章 18 -- 选中行前后增加两行】

请阅读【嵌入式开发学习必备专栏 之 Vim】 文章目录 选中行前后增加两行1. 定义函数2. 创建快捷键映射3. 保存并重新加载 .vimrc使用方法 重新选中实现步骤 1: 定义函数步骤 2: 绑定快捷键保存并重新加载 .vimrc使用方法 选中行前后增加两行 为了在 Vim 中实现这个功能&#x…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...