详解http协议

news2024/12/26 22:22:19

什么是HTTP协议

定义

Http协议即超文本传送协议 (HTTP-Hypertext transfer protocol) 。

它定义了浏览器(即万维网客户进程)怎样向万维网服务器请求万维网文档,以及服务器怎样把文档传送给浏览器。从层次的角度看,HTTP是面向(transaction-oriented)应用层协议,它是万维网上能够可靠地交换文件(包括文本、声音、图像等各种多媒体文件)的重要基础。并且详细地规定了客户端浏览器与服务器之间互相通信的规则。

http主要方法

http状态码

收到请求消息之后, Web 服务器会对其中的内容进行解析, 通过 URI和方法来判断“对什么”“进行怎样的操作”, 并根据这些要求来完成自己的工作, 然后将结果存放在响应消息中。 在响应消息的开头有一个状态码,它用来表示操作的执行结果是成功还是发生了错误。

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。

响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599)

HTTP状态码列表:

版本变迁

1991年,HTTP/0.9:支持GET请求方式获取文本数据(比如HTML),且不支持请求头,响应头,无法向服务器传递太多信息。

1996年,HTTP/1.0:支持POST、HEAD等请求方法,支持请求头、响应头等,支持更多种数据类型(不再局限于文本数据)浏览器的每次请求都需要与服务器建立一个TCP连接,请求处理完成后立即断开TCP连接。比如当前HTML在被浏览器解析时,发现有一个图片资源,就是再次建立TCP连接,然后关闭TCP连接。

1997年,HTTP/1.1:

  • 支持PUT,DELETE请求,采用持久连接,多个HTTP请求,可以共用一个TCP连接。

  • 这版协议使用最广泛。

2015,HTTP/2.0

2018,HTTP/3.0

HTTP报文格式

请求报文

HTTP请求报文第一行是请求行,其后继的行叫做首部行。每行由一个回车和换行符结束,最后一行再附加一个回车换行符。一个请求报文至少为一行。

  • 请求行:由请求方法、URL(包含参数)和协议版本组成

  • 请求头部:由多个key-value值组成

  • 空行:请求报文使用空行将请求头部和请求数据分隔

  • 请求数据:GET方法没有携带数据,POST方法会携带一个body

例:

响应报文

  • 状态行:由协议版本、状态码和状态值组成

  • 响应头:由多个key-value值组成

  • 空行:响应报文使用空行将响应头和响应体分隔

  • 响应体:响应数据,在上面是一段HTML

例:

HTTP传输原理

概述

以在浏览器中输入www.baidu.com为例:

  1. 对www.baidu.com这个网址进行DNS域名解析,得到对应的IP地址

  2. 根据这个IP,找到对应的服务器,发起TCP的三次握手

  3. 建立TCP连接后发起HTTP请求

  4. 服务器响应HTTP请求,浏览器得到html代码

  5. 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)(先得到html代码,才能去找这些资源)

  6. 浏览器对页面进行渲染呈现给用户

  7. 服务器关闭关闭TCP连接

详细步骤
  1. DNS解析

a)首先会搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存)

b)如果浏览器自身的缓存里面没有找到,那么浏览器会搜索系统自身的DNS缓存

c)如果还没有找到,那么尝试从 hosts文件里面去找

d)在前面三个过程都没获取到的情况下,就递归地去域名服务器去查找

  1. TCP连接建立(三次握手)

拿到域名对应的IP地址之后,User-Agent(一般指浏览器)会以一个随机端口(1024<端口<65535)向服务器的WEB程序(常用的有httpd,nginx)等的80端口。这个连接请求(原始的http请求经过TCP/IP4层模型的层层封包)到达服务器端后(这中间有各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别连接请求,解封包,一层一层地剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终达到WEB程序,最终建立了TCP/IP的连接

  1. 发起HTTP请求(建立连接后)

HTTP请求报文由三部分组成:请求行,请求头、空格、请求正文

  1. 服务器响应http请求,浏览器得到html代码

HTTP响应也由三部分组成:状态行,响应头,空格,消息体

状态行包括:协议版本、状态码、状态码描述

  1. 浏览器解析html代码,并请求html代码中的资源

浏览器拿到html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这个时候就用上keep-alive特性了,建立一次HTTP连接,可以请求多个资源,下载资源的顺序就是按照代码里面的顺序,但是由于每个资源大小不一样,而浏览器又是多线程请求资源,所以这里显示的顺序并不一定是代码里面的顺序。

  1. 浏览器对页面进行渲染呈现给用户

最后,浏览器利用自己内部的工作机制,把请求的静态资源和html代码进行渲染,渲染之后呈现给用户,浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。这个过程比较复杂,涉及到两个概念:reflow(回流)和repain(重绘)。

DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色,字体,等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少地减少reflow和repain。JS的解析是由浏览器中的JS解析引擎完成的。JS是单线程运行,JS有可能修改DOM结构,意味着JS执行完成前,后续所有资源的下载是没有必要的,所以JS是单线程,会阻塞后续资源下载。

  1. 服务器关闭关闭TCP连接

一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:

Connection:keep-alive 

TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽

什么是http2

http2:

  • 二进制格式:1.x是文本协议,然而2.0是以二进制帧为基本单位,可以说是一个二进制协议,将所有传输的信息分割为消息和帧,并采用二进制格式的编码,一帧中包含数据和标识符,使得网络传输变得高效而灵活;

  • 多路复用:2.0版本的多路复用多个请求共用一个连接,多个请求可以同时在一个TCP连接上并发,主要借助于二进制帧中的标识进行区分实现链路的复用;

  • 头部压缩:2.0版本使用HPACK算法对头部header数据进行压缩,从而减少请求的大小提高效率,这个非常好理解,之前每次发送都要带相同的header,显得很冗余,2.0版本对头部信息进行增量更新有效减少了头部数据的传输;

  • 服务端推送:在2.0版本允许服务器主动向客户端发送资源,这样在客户端可以起到加速的作用;

http2的重要改动:
  • 降低延迟(多路复用):使用多路复用来降低高延迟的问题,多路复用指的是使用Stream让多个请求可以共享一个TCP连接,解决HOL Blocking(head of line blocking)的问题,同时提升带宽利用率。

    • HTTP1.1中keep-alive用的是http pipelining本质上也是multiplexing,但是具体实现方案不理想 

    • 主流浏览器都默认禁止pipelining,也是因为HOL阻塞问题导致。

  • 服务端推送:HTTP1.X的推送都是半双工,所以在2.0是实现真正的服务端发起请求的全双工,另外在WebSocket在这一块大放异彩

  • 请求优先级:针对引入多路复用的一个兜底方案,多路复用使用多个Stream的时候容易单请求阻塞问题,也就是前文所说的和管道连接一样的问题,SPDY通过设置优先级的方式让重要请求优先处理,比如页面的内容应该先进行展示,之后再加载CSS文件美化以及加载脚本互动等等,实际减少用户不会在等待过程中关闭页面的几率

  • Header压缩:HTTP1.X的header很多时候都是多余的,所以2.0 会自动选择合适的压缩算法自动压缩请求加快请求和响应速度。

什么是http3

这个版本是划时代的改变,在HTTP3.0中,将弃用TCP协议,改为使用基于UDP协议的QUIC协议实现。需要注意QUIC是谷歌提出的(和2.0 的SPDY 一样),QUIC指的是快速 UDP Internet 连接,既然使用了UDP,那么也意味着网络可能存在丢包和稳定性下降,谷歌当然不会让这样的事情发生,所以他们提出的QUIC既可以保证稳定性,又可以保证SSL的兼容,因为HTTP3上来就会和TLS1.3一起上线。

基于这些原因,制定网络协议IETF的人马上基本都同意了QUIC的提案(太好了又能白嫖成果),于是HTTP3.0 就这样来了。但是这只是最基本的草案,后续的讨论中希望QUIC可以兼容其他的传输协议,最终的排序如下IP / UDP / QUIC / HTTP。另外TLS有一个细节优化是在进行连接的时候浏览器第一次就把自己的密钥交换的素材发给服务器,这样进一步缩短了交换的时间。

为什么要使用http3

为什么HTTP3.0要从协议根本上动刀,那是因为HTTP/2虽然解决了HTTP协议无法多路复用的问题,但是没有从TCP层面解决问题,具体的TCP问题体现如下:

  • RTT:RTT是Round Trip Time的缩写,简单来说就是通信一来一回的时间。

  • 队头阻塞,HTTP/2 多个请求跑在一个 TCP 连接中,如果此时序号较低的网络请求被阻塞,那么即使序列号较高的 TCP 段已经被接收了,应用层也无法从内核中读取到这部分数据,从 HTTP 视角看就是多个请求被阻塞了,并且页面也只是加载了一部分内容;

  • TCP 和 TLS 握手时延缩短:TCL 三次握手和 TLS 四次握手,共有 3-RTT 的时延,HTPT/3最终压缩到1 RTT(难以想象有多快);

  • 连接迁移需要重新连接,移动设备从 4G 网络环境切换到 WIFI 时,由于 TCP 是基于四元组来确认一条 TCP 连接的,那么网络环境变化后,就会导致 IP 地址或端口变化,于是 TCP 只能断开连接,然后再重新建立连接,切换网络环境的成本高

所以后续谷歌的研究方向转为研究QUIC,实际上就是改良UDP协议来解决TCP协议自身存在的问题

为什么http3选择UDP协议

这就引出另一个问题,为什么3.0有很多协议可以选择为什么使用UDP,通常有下面的几个点:

  • 基于TCP 协议的设备很多,兼容十分困难

  • TCP是Linux内部的重要组成,修改非常麻烦,或者说压根不敢动

  • UDP本身无连接的,没有建立连接和断连的成本

  • UDP数据包本身就不保证稳定传输所以不存在阻塞问题(属于爱要不要)

  • UDP改造相对其他协议改造成本低很多 

HTTP协议真的是无状态的么?

仔细阅读HTTP1.x和HTTP/2以及HTTP3.0三个版本的对比,其实会发现HTTP无状态的定义偷偷发生了变化的,为什么这么说?

我们需要弄清一个概念,那就是Cookie和Session虽然让HTTP实现了“有状态”,但是其实这和HTTP协议本身的概念是没有关系的。

Cookie和Session的出现根本目的是保证会话状态本身的可见性,两者通过创立多种独立的状态“模拟”用户上一次的访问状态,但是每一次的HTTP请求本身并不会依赖上一次HTTP的请求,单纯从广义的角度看待其实所有的服务都是有状态的,但是这并不会干扰HTTP1.X本身无状态的定义。

此外HTTP协议所谓的无状态指的是每个请求是完全独立的,在1.0备忘录定义中也可以看出一次HTTP连接其实就是一次TCP连接,到了HTTP1.1实现了一个TCP多个HTTP连接依然是可以看作独立的HTTP请求。

说了这么多,其实就是说HTTP1.X在不靠Cookie和Session扶着的时候看做无状态是对的,就好比游戏里面的角色本身的数值和武器附加值的对比,武器虽然可以让角色获得某种状态,但是这种状态并不是角色本身特有的,而是靠外力借来的。

然而随着互联网发展,到了HTTP/2和HTTP3之中HTTP本身拥有了“状态”定义,比如2.0关于HEADER压缩产生的HPACK算法(需要维护静态表和动态表),3.0还对HPACK算法再次升级为QPACK让传输更加高效。

所以总结就是严谨地来说HTTP1.X是无状态的,在Cookie和Session的辅助下实现了会话访问状态的保留。到了HTTP/2之后HTTP是有状态的, 因为在通信协议中出现了一些状态表来维护双方重复传递的Header字段减少数据传输。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1688485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录一个写SpringBoot中Hive数据可以正常提取但无法存到MySQL的bug

【背景】 我正在用SpringBoot框架写一个数据治理项目&#xff0c;目前所处阶段是将hive和hdfs中的元数据提取出来&#xff0c;存储到MySQL中&#xff0c;我的hive和hdfs上的数据存储在三台Linux服务器上&#xff08;hadoop102-104&#xff09;&#xff0c;MySQL在我本地Window…

C语言常用的内存操作函数

在C语言中经常会操作内存中的数据&#xff0c;下面来介绍一下常用的一些内存操作函数。 memcpy memcpy用于从source的位置开始向后复制num个字节到destination的内存位置&#xff0c;其函数原型如下&#xff1a; //destination是目标地址&#xff0c;source是源地址&#xff…

想要学会做抖店,每天重复这些步骤就可以了!

大家好&#xff0c;我是电商糖果 有很多朋友店铺开好之后&#xff0c;不知道每天要干嘛。 只知道把产品上架&#xff0c;然后等着出单。 说实话这种情况的朋友不是一个&#xff0c;而是很多。 糖果做小店也有很多年了&#xff0c;也开了多家店铺&#xff0c;下面就来给大家…

论Promise在前端江湖的地位及作用

系列文章&#xff1a; 先撸清楚&#xff1a;并发/并行、单线程/多线程、同步/异步 论Promise在前端江湖的地位及作用 前言 上篇文章阐述了并发/并行、单线程/多线程、同步/异步等概念&#xff0c;这篇将会分析Promise的江湖地位。 通过本篇文章&#xff0c;你将了解到&#x…

算法刷题笔记 数的范围(C++实现)(二分法重要例题)

文章目录 题目描述题目思路题目代码&#xff08;C&#xff09;题目感想 题目描述 给定一个按照升序排列的长度为n的整数数组&#xff0c;以及q个查询。对于每个查询&#xff0c;返回一个元素k的起始位置和终止位置&#xff08;位置从0开始计数&#xff09;。如果数组中不存在该…

Flutter 中如何优雅地使用弹框

日常开发中&#xff0c;Flutter 弹框&#xff08;Dialog&#xff09;是我们使用频率非常高的控件。无论是提示用户信息、确认用户操作&#xff0c;还是表单填写&#xff0c;弹框都能派上用场。然而&#xff0c;看似简单的弹框&#xff0c;实际使用起来却有不少坑和使用的技巧。…

轻松找回误删短信 | 超强安卓短信恢复神器

概括 我们都曾经历过不小心删除了重要消息&#xff0c;后来又后悔并认为可能无法恢复它们的情况。从技术上讲&#xff0c;该消息不会被删除&#xff1b;它会在您的 Android 手机上存储一段时间。 可以执行 Android 短信恢复&#xff0c;因为它需要一段时间才能从您的 Android…

JavaScript面试 题

1.延时加载JS有哪些方式 延时加载 :async defer 例如:<script defer type"type/javascript" srcscript.js></ script> defer:等html全部解析完成,才会执行js代码,顺次执行的 async: js和html解析是同步的,不是顺次执行js脚本(谁先加载完先执行谁)2.JS数…

黑龙江等保测评深入理解

“没有网络安全&#xff0c;就没有国家安全”&#xff0c;等级保护测评是指按照网络安全系统制定的一系列的防护过程&#xff0c;对已经有的和即将上线的商业服务的基础设施&#xff08;系统&#xff0c;数据库&#xff0c;中间件等&#xff09;所做的一系列的检查&#xff0c;…

代码随想录-Day18

513. 找树左下角的值 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 方法一&#xff1a;深度优先搜索 class Solution {int curVal 0;int curHeight 0;public int findBottomLeftValue(TreeNode roo…

Python筑基之旅-MySQL数据库(三)

目录 一、数据库操作 1、创建 1-1、用mysql-connector-python库 1-2、用PyMySQL库 1-3、用PeeWee库 1-4、用SQLAlchemy库 2、删除 2-1、用mysql-connector-python库 2-2、用PyMySQL库 2-3、用PeeWee库 2-4、用SQLAlchemy库 二、数据表操作 1、创建 1-1、用mysql-…

分布式理论--BASE

目录 是什么BASE 与 CAP&#xff0c;ACID 的区别BASE 和 Paxos 类共识算法的区别相关问题 是什么 BASE 理论是对 CAP 理论的进一步扩展主要强调在分布式系统中&#xff0c;为了获得更高的可用性和性能&#xff0c;可以放宽对一致性的要求&#xff0c;是对 CAP 中 AP 方案的一个…

卷爆短剧出海:五大关键,由AIGC重构

短剧高温下&#xff0c;谈谈AIGC的助攻路线。 短剧&#xff0c;一个席卷全球的高温赛道。 以往只是踏着霸总题材&#xff0c;如今&#xff0c;内容循着精品化、IP化的自然发展风向&#xff0c;给内容、制作、平台等产业全链都带来新机&#xff0c;也让短剧消费走向文化深处&am…

D60SB120-ASEMI整流桥D60SB120参数、封装、尺寸

编辑&#xff1a;ll D60SB120-ASEMI整流桥D60SB120参数、封装、尺寸 型号&#xff1a;D60SB120 品牌&#xff1a;ASEMI 封装&#xff1a;D-SB 批号&#xff1a;2024 最大重复峰值反向电压&#xff1a;1200V 最大正向平均整流电流(Vdss)&#xff1a;60A 功率(Pd)&#x…

Kubernetes 应用滚动更新

Kubernetes 应用版本号 在 Kubernetes 里&#xff0c;版本更新使用的不是 API 对象&#xff0c;而是两个命令&#xff1a;kubectl apply 和 kubectl rollout&#xff0c;当然它们也要搭配部署应用所需要的 Deployment、DaemonSet 等 YAML 文件。 在 Kubernetes 里应用都是以 …

uniapp开发vue3监听右滑返回操作,返回到指定页面

想要在uniapp框架中监听左滑或者右滑手势&#xff0c;需要使用touchstart和touchend两个api&#xff0c;因为没有原生的左右滑监听api&#xff0c;所以我们只能依靠这两个api来获取滑动开始时候的x坐标和滑动结束后的x坐标做比对&#xff0c;右滑的话&#xff0c;结束时候的x坐…

RabbitMQ(一)概述第一个应用程序

文章目录 概述AMQP和JMS官网安装开始第一个程序 概述 消息队列是实现应用程序和应用程序之间通信的中间件产品 AMQP和JMS 工作体系 官网 https://www.rabbitmq.com/ RabbitMQ是一款基于AMQP、由Erlang语言开发的消息队列产品 安装 # 拉取镜像 docker pull rabbitmq:3.13-m…

微信小程序画布显示图片绘制矩形选区

wxml <view class"page-body"><!-- 画布 --><view class"page-body-wrapper"><canvas canvas-id"myCanvas" type"2d" id"myCanvas" classmyCanvas bindtouchstart"touchStart" bindtouchmo…

UEFI EDK2源码学习(一)——环境安装

部署环境 vmvare15.0 ubuntu20.04 docker edk2 源码 具体步骤 docker安装 # 更新apt软件包索引 sudo apt-get update# 添加docker依赖 sudo apt-get install -y \apt-transport-https \ca-certificates \curl \gnupg-agent \software-properties-common# 添加docker 官方…

白嫖免费图床!CloudFlare R2太香了!

1 为啥要折腾搭建一个专属图床&#xff1f; 技术大佬写博客都用 md 格式&#xff0c;要在多平台发布&#xff0c;图片就得有外链后续如博客迁移&#xff0c;国内博客网站如掘金&#xff0c;简书&#xff0c;语雀等都做了防盗链&#xff0c;图片无法迁移 2 为啥选择CloudFlare…