HTTP协议必知必会详解

news2026/4/29 8:01:55
系列文章目录文章目录系列文章目录摘要一、开篇你真的分得清 HTTP 和 HTML 吗二、HTTP 的本质浏览器与服务器的 约定语言三、一次完整的 HTTP 请求到底经历了什么四、拆解 HTTP 报文请求与响应的内部结构4.1 HTTP 请求报文4.2 HTTP 响应报文五、无状态协议的 破局者Cookie 与 Session5.1 Cookie存在客户端的 身份小纸条5.2 Session存在服务端的 用户储物柜5.3 Session 的创建与管理六、解惑长连接和无状态真的矛盾吗总结摘要在学习 Web 容器、后端开发的过程中HTTP 协议是绕不开的基础。很多开发者虽然日常天天用 HTTP却对其核心机制一知半解HTTP 和 HTML 到底有什么区别无状态协议是怎么实现用户登录状态保持的长连接和无状态为什么不矛盾本文将从 HTTP 的本质出发带你拆解一次完整的 HTTP 请求过程分析请求与响应的报文结构深入讲解 Cookie 与 Session 的工作原理同时解答很多开发者容易混淆的长连接与无状态的关系帮你彻底搞懂 HTTP 协议的核心知识点为深入学习 Tomcat、Jetty 等 Web 容器打下坚实基础。一、开篇你真的分得清 HTTP 和 HTML 吗在深入学习 Tomcat、Jetty 这类 Web 容器之前我想先问你一个问题HTTP 和 HTML 有什么区别这其实是一个很好的入门测试能帮你快速检验自己对 HTTP 协议的理解程度。因为 Tomcat 和 Jetty 本质上就是HTTP 服务器 Servlet 容器如果连最基础的 HTTP 协议都没搞懂想要深入理解 Web 容器的工作原理无异于空中楼阁。如果你对这个问题还有些迟疑没关系跟着本文一起我们重新把 HTTP 协议的核心知识点梳理一遍。二、HTTP 的本质浏览器与服务器的 “约定语言”很多人都知道HTTP 是应用层协议基于 TCP/IP 协议来传输数据比如 HTML 文件、图片、接口数据等等。但很多人忽略了一点HTTP 协议本身不关心数据包在网络里是怎么传输的它核心要解决的是客户端和服务器之间的通信格式问题。举个很简单的例子当你在浏览器里输入网址想要从服务器获取一个 HTML 页面的时候浏览器要做两件事和服务器建立 Socket 连接这是网络通信的基础有了这个连接双方才能收发数据。把自己的需求打包成数据通过这个连接发给服务器。第一步很好理解那第二步里浏览器要怎么告诉服务器我想要什么我是要获取数据还是要提交表单我想要的是哪个资源是首页还是用户列表我能接收什么格式的返回数据能不能支持压缩这些信息如果没有一个统一的格式服务器根本没办法解析。比如浏览器发了一堆乱码一样的字符服务器怎么知道你要干嘛三、一次完整的 HTTP 请求到底经历了什么很多开发者天天发 HTTP 请求却从来没认真想过从你点击链接到页面展示出来这中间到底发生了多少步我们来完整走一遍这个流程触发请求用户在浏览器里输入网址回车或者点击了一个超链接浏览器捕获到这个操作知道要发起网络请求了。发起 TCP 连接请求浏览器根据域名解析出服务器的 IP 地址然后向服务器的对应端口默认 80发起 TCP 连接请求。TCP 三次握手建立连接服务器收到连接请求后双方经过 TCP 三次握手确认彼此的收发能力都正常正式建立起 TCP 连接。打包请求数据浏览器把用户的请求按照 HTTP 协议的格式打包成一个 HTTP 请求报文。网络传输请求把这个报文通过之前建立的 TCP 连接发送给服务器经过网络路由最终到达服务器的应用程序。服务器解析请求服务器的 HTTP 服务程序比如 Tomcat拿到这个报文按照 HTTP 协议的格式解包解析出客户端的需求你要访问哪个路径用的什么方法传了什么参数处理业务逻辑服务器根据解析出来的请求处理对应的业务如果是静态资源就直接读文件如果是动态接口就调用对应的后端程序拿到处理结果。打包响应数据服务器把处理结果再按照 HTTP 协议的格式打包成响应报文。网络传输响应把响应报文通过 TCP 连接发回给浏览器经过网络传输到达客户端。浏览器解析响应浏览器拿到响应报文按照 HTTP 协议解包拿到里面的内容如果是 HTML就开始解析渲染页面。页面渲染展示浏览器把解析好的 HTML、CSS、JS 处理完最终把页面展示给用户。而我们常说的 Tomcat、Jetty 这类 Web 容器在这个过程中负责的就是接受连接、解析请求、处理请求、发送响应这几个核心步骤。要注意的是一台服务器可能要同时处理成千上万的浏览器请求如果一个个串行处理效率会极低。所以 Tomcat 这类容器都会用多线程技术把这些步骤并行化来提升并发处理能力这也是我们后续深入学习 Web 容器的核心重点之一。四、拆解 HTTP 报文请求与响应的内部结构说了这么多格式那 HTTP 的报文到底长什么样我们拿一个真实的登录请求来拆解一下你一看就懂了。4.1 HTTP 请求报文这是极客时间登录接口的真实请求我们把它整理成标准格式POST /account/ticket/login HTTP/1.1 Accept: application/json, text/plain, */* Accept-Encoding: gzip, deflate, br Accept-Language: en,de;q0.9,zh-CN;q0.8,zh;q0.7,en-US;q0.6 Connection: keep-alive Content-Length: 115 Content-Type: application/json Host: account.geekbang.org User-Agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 {country:86,cellphone:139********,password:*******,captcha:,remember:1,platform:web}你可以看到一个完整的 HTTP 请求报文分为三个部分请求行就是第一行包含三个信息请求方法这里是POST表示这是一个提交数据的请求除此之外还有 GET、PUT、DELETE 等常用方法。请求路径/account/ticket/login表示要访问的服务器接口路径。HTTP 版本HTTP/1.1表示用的是 1.1 版本的 HTTP 协议。请求头从第二行开始到空行之前的部分都是请求头这是一系列的键值对用来传递一些附加的信息Accept告诉服务器我客户端能接收什么类型的返回数据。Accept-Encoding我支持的压缩方式这样服务器可以返回压缩后的数据减少传输体积。Content-Type我这次请求的正文是什么格式这里是application/json说明正文是 JSON 格式的数据。Host要访问的主机域名因为一台服务器可能部署了多个网站靠这个来区分。User-Agent客户端的标识告诉服务器我是什么浏览器、什么版本服务器可以根据这个做不同的适配。请求正文空行之后的部分就是真正要传输的业务数据这里就是我们提交的登录账号密码信息。当这个请求到达 Tomcat 之后Tomcat 会把这些字节流解析成一个Request对象把请求行、请求头、正文这些信息都封装进去然后交给 Web 应用去处理。4.2 HTTP 响应报文处理完之后服务器会返回响应同样的响应报文也分为三个部分我们还是看这个登录请求的响应HTTP/1.1 200 OK Connection: keep-alive Content-Type: application/json; charsetUTF-8 Date: Sun, 24 Feb 2019 11:50:20 GMT Set-Cookie: expiresWed, 06-Mar-2019 GMT; Max-Age864000; path/; domain.geekbang.org; HttpOnly {code:0,msg:登录成功,data:{token:xxxxxx}}状态行第一行同样三个信息HTTP 版本HTTP/1.1状态码200表示请求处理成功除此之外还有 404找不到资源、500服务器错误、302重定向等常用状态码。状态描述OK对状态码的文本描述。响应头同样是键值对传递附加信息比如这里的Set-Cookie就是服务器告诉浏览器要把这个 Cookie 存起来下次请求带上。响应正文空行之后的部分就是服务器返回的业务数据这里是登录的结果信息。Web 应用处理完请求之后会生成一个Response对象Tomcat 再把这个对象转换成标准的 HTTP 响应报文发给浏览器一次请求就完成了。五、无状态协议的 “破局者”Cookie 与 SessionHTTP 协议有一个很重要的特点无状态。什么意思就是协议本身请求和请求之间是没有任何关系的服务器不会记得你上一次请求了什么也不会记得你是谁。每一次请求对服务器来说都是一次全新的、独立的请求。这就带来了一个问题比如你登录淘宝把商品加入购物车然后刷新页面服务器如果不记得你是谁那它就会以为你是个新用户提示你未登录购物车也空了这显然是不能接受的。所以为了让服务器能识别用户在无状态的 HTTP 协议之上就诞生了 Cookie 和 Session 这两个技术。5.1 Cookie存在客户端的 “身份小纸条”Cookie 本质上就是服务器让浏览器存在本地的一份小数据。当你第一次登录服务器的时候服务器在响应头里通过Set-Cookie告诉浏览器“你把这个用户标识存起来下次给我发请求的时候记得把这个信息带上”。然后浏览器就会把这个 Cookie 存在本地之后每次给这个服务器发请求的时候都会自动在请求头里带上这个 Cookie。这样服务器拿到 Cookie就能识别出你是谁了。简单来说Cookie 就是一份存在用户本地的 “小纸条”每次请求都带着它让服务器能认出你。5.2 Session存在服务端的 “用户储物柜”但是 Cookie 有个问题它是存在用户本地的而且是明文传输的如果我们把用户的账号、密码这些敏感信息都存在 Cookie 里很容易被窃取有很大的安全隐患。所以 Session 就出现了。Session 可以理解为服务器在自己的内存里给每个用户开辟了一个 “储物柜”用来存用户的状态信息比如用户 ID、登录状态这些。那服务器怎么把请求和这个储物柜对应起来呢很简单服务器给每个储物柜生成一个唯一的编号也就是Session ID然后把这个编号通过 Cookie 发给浏览器让浏览器存起来。之后每次请求浏览器带着这个 Session ID 的 Cookie 过来服务器拿到这个 ID就能找到对应的那个储物柜拿到用户的状态信息了。这样一来敏感的用户信息都存在服务器端传到客户端的只有一个没有意义的 Session ID既安全又减少了网络传输的体积因为不用每次都传一大堆用户信息了。5.3 Session 的创建与管理那 Session 是什么时候创建的呢是在服务器端创建的。以 Java Web 为例当你的 Web 应用调用HttpServletRequest.getSession()方法的时候Tomcat 这类 Web 容器就会检查请求里有没有 Session ID如果没有就会创建一个新的 Session生成唯一的 Session ID然后把这个 ID 通过 Cookie 返回给浏览器。为了保证 Session 的可靠性Tomcat 还提供了多种持久化方案不会把 Session 只存在单机内存里不然服务器重启用户的登录状态就没了。通常会把 Session 存在 Redis 这类高性能的中间件里这样就算服务器集群部署所有节点都能共享 Session不会出现用户在不同节点之间切换就掉线的问题。同时 Session 有过期时间Tomcat 会开一个后台线程定期清理过期的 Session释放服务器的资源。六、解惑长连接和无状态真的矛盾吗很多人学到这里都会有一个疑问HTTP 是无状态的多个请求之间没有关系但是 HTTP/1.1 里又引入了长连接多个请求可以共用同一个 TCP 连接这不是矛盾了吗其实这完全不矛盾因为这两个东西根本就不是一个层面的东西。我们先回顾一下在 HTTP/1.0 的时候每次请求都要新建一个 TCP 连接请求完了就把连接关掉。就好比你每次寄信都要新修一条路寄完就把路拆了下次再寄再修这显然效率很低修路的开销太大了。所以 HTTP/1.1 引入了长连接通过Connection: keep-alive来开启默认就是开启的。意思是这个 TCP 连接一次请求完了不关掉下次你还要给这个服务器发请求就直接用这个已经修好的路不用再重新修路了省下了 TCP 三次握手的开销。但是长连接是 TCP 层面的连接复用而 HTTP 的无状态是应用层的协议特性。也就是说就算多个请求共用同一个 TCP 连接这些请求本身还是独立的每个请求都包含了服务器处理这个请求需要的所有信息服务器不需要记住上一个请求的状态就能处理当前的请求。就好比路是同一条路但是你寄的每一封信都是独立的每封信里都写好了完整的收件人、内容收信人不需要记得你上一封信寄了什么拿到这封信就能处理。这两者完全不冲突长连接只是优化了传输层的效率并没有改变 HTTP 协议本身无状态的特性。而且要注意HTTP/1.1 的长连接虽然解决了连接复用的问题但是带来了一个新的问题队头阻塞。因为同一个连接里的请求是要排队处理的前面的请求没处理完后面的请求就得等着。这个问题直到 HTTP/2.0通过二进制分帧的方式才彻底解决。总结到这里我们把 HTTP 协议的核心知识点都梳理了一遍总结一下HTTP 的本质它是浏览器和服务器之间约定的通信格式HTTP 是 “信封”用来规定怎么传输数据而 HTML、JSON 这些是 “信的内容”是传输的数据本身。请求流程一次完整的 HTTP 请求要经过 TCP 连接建立、请求打包传输、服务器处理、响应打包返回、浏览器渲染这一系列步骤。报文结构HTTP 的请求和响应都分为行、头、正文三个部分通过标准化的格式让双方能够互相解析。状态保持HTTP 本身是无状态的所以我们用 Cookie 来在客户端存标识用 Session 来在服务端存用户状态实现了用户登录这类有状态的功能。长连接与无状态两者并不矛盾长连接是 TCP 层的连接复用用来提升传输效率而无状态是 HTTP 应用层的特性两者互不影响。搞懂了这些你就已经掌握了 HTTP 协议的核心必知必会的知识点这也是你深入学习 Web 容器、后端开发的重要基础。不知道你有没有搞懂这些知识点你在日常开发中有没有遇到过和 HTTP 协议相关的有趣问题欢迎在评论区留言讨论。

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

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

相关文章

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…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…