开篇:从一个简单的场景说起
想象一下,现在是早上8点,你刚醒来,拿起手机打开浏览器,输入www.news.com,然后按下回车键。几秒钟后,屏幕上就出现了今天的新闻头条、图片、视频,甚至还有一些互动评论。
这一切看起来理所当然,对吧?但你有没有想过,这个过程背后到底发生了什么?你的手机是怎么”告诉”远在几千公里外的服务器”嘿,我想看新闻”的?那台服务器又是怎么”回复”你,把那些文字、图片、视频准确无误地送到你手机上的?
这就是HTTP在做的事情。它就像是互联网世界里的一种通用语言,让你的设备和服务器能够相互理解、相互对话。
第一章:HTTP到底是什么?
1.1 名字的由来
HTTP是”HyperText Transfer Protocol”的缩写,中文翻译过来叫”超文本传输协议”。我知道,这个名字听起来有点学术,有点枯燥。但别担心,我们一点点来拆解它。
HyperText(超文本):这个词在今天看来可能有点过时,但在互联网早期,它代表了一种革命性的想法。什么是超文本?就是那种不仅仅包含普通文字,还包含链接、图片、甚至视频的”文本”。你点击一个链接就能跳转到另一个页面,这就是”超”的含义——它超越了传统纸质文档的限制。
Transfer(传输):这个好理解,就是把东西从一个地方搬到另一个地方。在HTTP的语境里,就是把网页内容从服务器传到你的设备上。
Protocol(协议):协议是什么?简单说,就是一套大家都同意遵守的规则。就像开车要靠右行(或靠左行),红灯停绿灯行,这些都是交通协议。HTTP就是互联网上传输信息的一套规则。
1.2 为什么需要HTTP?
让我用一个类比来解释。假设你在中国,想给美国的朋友寄一封信。你不能只是把信扔到空中,期望它自己飞到美国去,对吧?你需要:
- 把信装进信封
- 在信封上写清楚收件人地址
- 贴上邮票
- 投进邮筒
- 邮局按照既定的规则和路线把信送到目的地
HTTP就扮演着类似的角色。它定义了:
- 你的浏览器应该怎么”包装”你的请求
- 请求里应该包含哪些信息
- 服务器应该怎么理解这个请求
- 服务器应该怎么回复
- 回复的内容应该怎么组织

没有这套规则,互联网就会变成一团混乱。就像如果没有统一的邮政系统,每个人都用自己的方式寄信,那整个系统就崩溃了。
1.3 HTTP的历史小故事
HTTP诞生于1989年,发明者是英国科学家蒂姆·伯纳斯-李(Tim Berners-Lee)。当时他在欧洲核子研究中心(CERN)工作,面临一个问题:全世界的科学家们都在做研究,产生大量的文档和数据,但这些信息都分散在不同的电脑上,共享起来非常困难。
于是伯纳斯-李想:能不能创造一种方式,让人们可以轻松地在不同电脑之间分享和访问信息?就这样,他发明了三样东西:
- HTML(用来写网页)
- URL(网址,用来定位资源)
- HTTP(用来传输这些资源)
这三样东西加在一起,就是我们今天所说的”万维网”(World Wide Web)的基础。是的,WWW和互联网不完全是一回事——互联网是基础设施,而万维网是建立在互联网上的一个应用。
最初的HTTP非常简单,只有一个命令:GET(获取)。你告诉服务器你想要什么,服务器就把东西给你,然后连接就断开了。就像你去便利店买瓶水,买完就走,不会和店员建立长期关系。
但随着时间推移,人们发现需要做更复杂的事情。不只是”获取”信息,还要”提交”信息(比如填写表单)、”更新”信息、”删除”信息等等。于是HTTP不断进化,有了HTTP/0.9、HTTP/1.0、HTTP/1.1,再到今天的HTTP/2和HTTP/3。
第二章:HTTP是怎么工作的?
2.1 请求-响应模式
HTTP的工作方式非常直观:就是”你问我答”。专业术语叫”请求-响应模式”(Request-Response Model)。
你(客户端)发起一个请求:”我想要这个网页。” 服务器收到请求后回复:”好的,给你。”
就这么简单。但魔鬼藏在细节里。让我们深入看看这个过程。
2.2 一个HTTP请求的诞生
当你在浏览器地址栏输入”www.example.com”并按下回车,会发生这样的事情:
第1步:域名解析 浏览器首先要把”www.example.com”这个人类可读的地址转换成电脑能理解的IP地址(比如192.0.2.1)。这个过程叫DNS查询,不过这不是HTTP的一部分,但它是必要的前置步骤。
第2步:建立连接 浏览器向服务器的IP地址发起连接请求。这里用到的是TCP协议(HTTP是建立在TCP之上的)。你可以把TCP想象成打电话前的”拨号”过程——在真正开始对话前,要先建立起一条通信线路。
第3步:发送HTTP请求 连接建立后,浏览器就发送一个HTTP请求。这个请求是一段文本,看起来可能是这样的:
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: keep-alive
让我们逐行解释:
- GET / HTTP/1.1:这是请求行。GET是方法(待会儿详细说),”/”是路径(这里表示网站根目录),HTTP/1.1是协议版本。
- Host: www.example.com:告诉服务器你要访问哪个网站(因为一台服务器可能托管多个网站)。
- User-Agent:告诉服务器你用的什么浏览器和操作系统。有些网站会根据这个返回不同的内容(比如给手机返回移动版页面)。
- Accept:告诉服务器你能接受什么类型的内容。
- Accept-Language:告诉服务器你偏好的语言。
- Connection: keep-alive:告诉服务器”咱们保持连接吧,我可能还要请求其他资源”。
这些信息叫”请求头”(Request Headers)。它们就像是信封上的各种标注,帮助服务器更好地理解和处理你的请求。
2.3 服务器的响应
服务器收到请求后,会处理它,然后发回一个响应。响应看起来可能是这样的:
HTTP/1.1 200 OK
Date: Fri, 09 Jan 2026 12:00:00 GMT
Server: Apache/2.4.41
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
Connection: keep-alive
<!DOCTYPE html>
<html>
<head>
<title>欢迎来到示例网站</title>
</head>
<body>
<h1>你好,世界!</h1>
</body>
</html>
同样,我们来拆解一下:
- HTTP/1.1 200 OK:这是状态行。200是状态码,表示”一切正常”。OK是状态描述。
- Date:服务器生成响应的时间。
- Server:服务器软件的信息。
- Content-Type:告诉浏览器返回的是什么类型的内容(这里是HTML)。
- Content-Length:内容的长度(以字节计算)。
- Connection: keep-alive:同意保持连接。
然后是一个空行(很重要!),接下来就是实际的内容——HTML代码。
2.4 无状态的特性
这里要说一个HTTP很重要的特点:它是无状态的(Stateless)。
什么意思呢?就是说,HTTP本身不记得你是谁。每次请求都是独立的,服务器不会记住你之前发过什么请求。
这就像你每次去同一家餐厅,服务员都不记得你,都要重新点菜、重新介绍自己。这听起来很不方便,对吧?
那为什么要这样设计呢?因为简单!服务器不需要维护每个用户的状态信息,这样就能同时服务成千上万的用户而不会被搞晕。
但确实,很多时候我们需要”记住”用户。比如你登录一个网站后,希望在浏览不同页面时保持登录状态,而不是每次都要重新输入用户名密码。
怎么解决呢?有几种方法,最常见的是使用Cookie。Cookie就像是餐厅给你的会员卡,虽然服务员不记得你,但你下次来的时候出示会员卡,他们就能查到你的信息了。
第三章:HTTP的方法(动词)
如果说HTTP是一种语言,那么HTTP方法就是这种语言的”动词”。它们定义了你想对资源做什么操作。

3.1 GET:获取资源
GET是最常用的方法,它的意思是”请给我这个资源”。
当你在浏览器中输入网址,或者点击一个链接,发送的都是GET请求。GET请求应该是”安全”的,意思是它只是获取信息,不会修改服务器上的任何东西。
举个例子:
GET /articles/123 HTTP/1.1
Host: blog.example.com
这是在说:”请给我博客上ID为123的那篇文章。”
GET请求可以带参数,通常放在URL里:
GET /search?q=HTTP教程&page=1 HTTP/1.1
这是在搜索关于”HTTP教程”的内容,显示第1页结果。
3.2 POST:提交数据
POST用来向服务器提交数据。最常见的场景是填写表单,比如注册账号、发布评论、上传文件等。
与GET不同,POST请求的数据通常放在请求体(Request Body)里,而不是URL中。
例如:
POST /api/register HTTP/1.1
Host: example.com
Content-Type: application/json
{
"username": "zhangsan",
"email": "zhangsan@example.com",
"password": "123456"
}
这是在注册一个新用户。注意数据是放在请求体里的JSON格式。
POST请求会改变服务器的状态(比如创建了一个新用户),所以它不是”安全”的。
3.3 PUT:更新资源
PUT用来更新已有的资源。比如你想修改你的个人资料:
PUT /users/123 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"email": "newemail@example.com",
"bio": "这是我的新简介"
}
这是在更新ID为123的用户的信息。
PUT的特点是”幂等”(Idempotent),意思是你发送同样的请求多次,结果应该是一样的。就像你设置空调温度为25度,不管你按几次,温度都是25度。
3.4 DELETE:删除资源
DELETE用来删除资源。比如:
DELETE /articles/456 HTTP/1.1
Host: blog.example.com
这是在删除ID为456的文章。
DELETE也是幂等的——删除一次和删除多次,结果都是资源被删除了。
3.5 其他方法
还有一些不太常用但也很有用的方法:
- HEAD:和GET类似,但只返回响应头,不返回实际内容。用于检查资源是否存在或获取元数据。
- OPTIONS:询问服务器支持哪些HTTP方法。
- PATCH:部分更新资源(PUT是完整替换)。
3.6 方法的安全性和幂等性
这里有两个重要概念:
安全性:不会修改服务器资源的方法被认为是安全的。GET和HEAD是安全的,POST、PUT、DELETE不是。
幂等性:多次执行同一操作,结果与执行一次相同。GET、PUT、DELETE是幂等的,POST不是(每次POST可能创建不同的资源)。
为什么这很重要?因为在网络不稳定的情况下,请求可能会被重复发送。如果一个操作是幂等的,重复发送就不会造成问题。但如果你重复发送POST请求,可能就会创建多个重复的订单——这可不好!
第四章:HTTP状态码:服务器的回应
当服务器处理完你的请求,它会返回一个状态码,告诉你结果如何。状态码是一个三位数,而且有规律:
- 1xx(信息性):请求已接收,继续处理
- 2xx(成功):请求已成功处理
- 3xx(重定向):需要进一步操作才能完成请求
- 4xx(客户端错误):请求有错误
- 5xx(服务器错误):服务器处理请求时出错
让我们看看一些常见的状态码:
4.1 200 OK:一切顺利
这是最常见的成功状态码。服务器成功处理了你的请求,并返回了你要的内容。
4.2 201 Created:已创建
通常用于POST请求成功创建了新资源。比如你成功注册了账号,或者发布了一篇新文章。
4.3 204 No Content:成功但无内容
请求成功了,但没有内容返回。比如你删除了一个资源,服务器确认删除成功,但不需要返回任何东西。
4.4 301 Moved Permanently:永久重定向
资源被永久移动到新位置了。比如一个网站改了域名,旧域名会301重定向到新域名。浏览器会自动跳转,并且记住新地址。
4.5 302 Found:临时重定向
资源临时在另一个位置。浏览器会跳转,但不会记住新地址(因为是临时的)。
4.6 304 Not Modified:未修改
这个很有趣。它用于缓存场景。浏览器问:”这个资源我上次访问后有更新吗?”服务器回答:”没有更新(304),用你缓存的版本就行。”这样就不需要重新传输整个资源,节省了带宽。
4.7 400 Bad Request:错误的请求
你的请求有问题,服务器看不懂。可能是格式错误,或者缺少必要参数。
4.8 401 Unauthorized:未授权
你需要登录才能访问这个资源。就像你想进一个需要会员才能进的俱乐部,保安拦住你说:”你没有权限。”
4.9 403 Forbidden:禁止访问
服务器理解你的请求,但拒绝执行。即使你登录了,你也没有权限访问这个资源。就像你是会员,但试图进入”员工专用区域”。
4.10 404 Not Found:找不到
这可能是最著名的状态码了。它表示服务器找不到你请求的资源。可能是网址打错了,或者资源被删除了。
我们都见过404错误页面,对吧?很多网站会设计有趣的404页面来缓解用户的失望。
4.11 405 Method Not Allowed:方法不允许
你用了错误的HTTP方法。比如某个接口只接受POST,你却发了GET请求。
4.12 429 Too Many Requests:请求过多
你发送请求太频繁了,服务器让你慢点。这是一种保护机制,防止服务器被滥用。
4.13 500 Internal Server Error:服务器内部错误
服务器出问题了。可能是代码有bug,或者数据库连接失败。这不是你的错,是服务器的问题。
4.14 502 Bad Gateway:网关错误
服务器作为网关或代理时,从上游服务器收到了无效响应。通常是服务器之间通信出了问题。
4.15 503 Service Unavailable:服务不可用
服务器暂时无法处理请求。可能是过载了,或者正在维护。通常是临时状态。
第五章:HTTP头部:额外的信息
HTTP头部(Headers)就像是信件的附加说明。它们提供了关于请求或响应的额外信息,但不是实际内容本身。
头部由”键-值”对组成,格式是Name: Value。
5.1 常见的请求头
Host 指定请求的服务器域名和端口号。这是HTTP/1.1中唯一必需的头部。
User-Agent 标识发送请求的客户端软件。网站可以根据这个返回不同的内容版本。
Accept 告诉服务器客户端能够处理的内容类型。比如:
Accept: text/html– 我要HTMLAccept: application/json– 我要JSONAccept: image/*– 我接受任何图片格式
Accept-Language 客户端偏好的语言。比如Accept-Language: zh-CN,zh;q=0.9,en;q=0.8表示优先中文,其次英文。
Accept-Encoding 客户端支持的内容编码(压缩)方式。比如Accept-Encoding: gzip, deflate表示支持gzip和deflate压缩。
Cookie 发送之前服务器设置的Cookie。这是保持状态的主要方式。
Referer(注意拼写,确实少了一个r) 指示请求是从哪个页面跳转过来的。对网站统计和安全都有用。
Authorization 包含认证信息,用于访问需要权限的资源。
5.2 常见的响应头
Content-Type 指示返回内容的类型。比如:
Content-Type: text/html; charset=UTF-8– HTML文档Content-Type: application/json– JSON数据Content-Type: image/png– PNG图片
Content-Length 内容的长度(字节数)。帮助客户端知道要接收多少数据。
Set-Cookie 服务器设置Cookie。浏览器会保存这个Cookie,并在后续请求中发送回去。
Cache-Control 控制缓存行为。比如:
Cache-Control: no-cache– 不要使用缓存,每次都要验证Cache-Control: max-age=3600– 这个内容在3600秒(1小时)内都是新鲜的
Location 用于重定向,指示资源的新位置。
Server 服务器软件信息。
Date 消息产生的日期和时间。
5.3 CORS相关头部
CORS(跨域资源共享)是一个重要的安全机制。简单说,浏览器默认不允许网页向不同域名的服务器发送请求。但有时我们需要这样做,CORS头部就是用来授权的。
Access-Control-Allow-Origin 指定哪些域名可以访问资源。比如:
Access-Control-Allow-Origin: *– 允许任何域名访问Access-Control-Allow-Origin: https://example.com– 只允许example.com访问
Access-Control-Allow-Methods 指定允许的HTTP方法。
Access-Control-Allow-Headers 指定允许的请求头。
第六章:HTTPS:HTTP的安全升级版
6.1 为什么需要HTTPS?

HTTP有一个严重的问题:它是明文传输的。就像你给朋友写信,但不用信封,直接把纸张寄出去,邮递员、快递员,任何经手的人都能看到信的内容。
在互联网上,你的请求要经过很多”中间人”才能到达服务器:你的路由器、ISP(互联网服务提供商)、各种网络节点等等。如果用HTTP,这些中间人都能看到你传输的内容。
更糟糕的是,恶意的中间人还可以篡改内容。想象一下,你访问银行网站,输入账号密码,结果被中间人截获并修改,把钱转到他们的账户——这就是”中间人攻击”(Man-in-the-Middle Attack)。
HTTPS就是为了解决这些问题而生的。
6.2 HTTPS是什么?
HTTPS就是HTTP + SSL/TLS。SSL(Secure Sockets Layer)和它的继任者TLS(Transport Layer Security)是加密协议,用来保护数据传输的安全。
HTTPS做三件事:
- 加密:数据被加密后传输,即使被截获也无法读取
- 完整性:确保数据在传输过程中没有被篡改
- 身份认证:确认你真的在和正确的服务器通信,而不是冒充者
6.3 HTTPS是怎么工作的?
这里涉及到一些密码学知识,我尽量用通俗的语言解释。
对称加密和非对称加密
加密有两种主要方式:
- 对称加密:用同一个密钥加密和解密。就像一把钥匙既能锁门又能开门。速度快,但问题是你怎么安全地把密钥交给对方?
- 非对称加密:有一对密钥,公钥和私钥。公钥加密的内容只能用私钥解密,私钥加密的内容只能用公钥解密。公钥可以公开,私钥必须保密。速度较慢,但很安全。
HTTPS的握手过程
当你访问一个HTTPS网站时,会发生这样的过程(叫SSL/TLS握手):
- 客户端问候:你的浏览器说”你好,我支持这些加密算法”
- 服务器问候:服务器回复”好的,我们用这个算法,这是我的数字证书”
- 证书验证:浏览器检查证书是否有效(是否由可信机构颁发,是否过期等)
- 密钥交换:双方协商出一个对称密钥(用非对称加密安全地交换)
- 开始加密通信:之后的所有数据都用协商好的对称密钥加密
为什么不全程用非对称加密?因为太慢了。所以HTTPS聪明地结合了两种加密方式:用非对称加密来安全地交换对称密钥,然后用对称加密来传输实际数据。
6.4 数字证书
数字证书就像是服务器的”身份证”。它由证书颁发机构(CA,Certificate Authority)颁发,包含了服务器的公钥和身份信息。
当你访问https://www.example.com时,浏览器会检查:
- 证书是否由可信的CA颁发?
- 证书是否过期?
- 证书上的域名是否匹配你访问的域名?
如果一切正常,浏览器地址栏会显示一个小锁图标,表示连接是安全的。如果有问题,浏览器会警告你。
6.5 HTTPS的代价
HTTPS确实更安全,但也有代价:
- 速度:加密和解密需要计算,握手过程也需要时间(虽然现代计算机上这个影响已经很小了)
- 成本:需要购买和维护SSL/TLS证书(不过现在有免费证书,比如Let’s Encrypt)
- 复杂性:配置和管理比HTTP稍微复杂一些
但这些代价是值得的。事实上,现在主流观点是所有网站都应该使用HTTPS,不仅是涉及敏感信息的网站。Google甚至会在搜索排名中给HTTPS网站更高的权重。
第七章:HTTP的演进
7.1 HTTP/0.9:最初的版本
1991年的HTTP/0.9极其简单,只有一个命令:GET。而且只能传输HTML文档。
请求看起来是这样的:
GET /index.html
响应就是HTML内容本身,没有头部,没有状态码,没有别的。
7.2 HTTP/1.0:增加功能
1996年的HTTP/1.0带来了很多改进:
- 增加了POST和HEAD方法
- 增加了请求头和响应头
- 增加了状态码
- 可以传输其他类型的内容(图片、视频等)
但每个请求都需要建立新的TCP连接,然后关闭。这很低效,就像你去商店买十样东西,每买一样都要出门再进门一次。
7.3 HTTP/1.1:持久连接
1999年的HTTP/1.1是一个重大改进,至今仍被广泛使用。主要改进:
持久连接:连接可以保持打开,处理多个请求。就像你进了商店,可以一次买完所有东西再出去。
管道化(Pipelining):可以在不等待响应的情况下发送多个请求。不过这个特性存在问题,实际使用并不多。
分块传输:可以把响应分成多个块传输,不需要事先知道总长度。
更多的缓存控制:更精细的缓存策略。
Host头部必需:使得一台服务器可以托管多个网站。
但HTTP/1.1也有问题:
队头阻塞(Head-of-Line Blocking):如果第一个请求很慢,后面的请求都要等待。
头部臃肿:每个请求都要发送完整的头部,很多是重复的。
明文传输:安全性问题(这个通过HTTPS解决)。
7.4 HTTP/2:性能飞跃
2015年推出的HTTP/2带来了革命性的改进:
二进制协议:不再是文本,而是二进制,更高效但不再人类可读。
多路复用:在同一个连接上可以并发处理多个请求和响应,彻底解决了队头阻塞问题。
头部压缩:使用HPACK算法压缩头部,大大减少了数据传输量。
服务器推送:服务器可以主动向客户端推送资源。比如当你请求一个HTML页面时,服务器知道你接下来会需要CSS和JS文件,就主动推送给你。
HTTP/2完全兼容HTTP/1.1的语义,只是传输方式变了。对开发者来说,几乎不需要改变代码。
7.5 HTTP/3:基于QUIC
HTTP/3是最新的版本(正式发布于2022年),它的最大变化是放弃了TCP,改用QUIC协议(基于UDP)。
为什么?因为TCP虽然可靠,但有一些固有的问题:
- 握手慢:TCP需要三次握手建立连接,HTTPS还要TLS握手
- 队头阻塞:虽然HTTP/2解决了应用层的队头阻塞,但TCP层仍然存在——如果一个数据包丢失,后面的包都要等
- 连接迁移:换网络(比如从WiFi切换到4G)连接就断了
QUIC解决了这些问题:
- 更快的握手:0-RTT连接建立(第一次除外)
- 内置加密:安全性是内置的,不是可选的
- 无队头阻塞:每个流是独立的
- 连接迁移:换网络连接不断
HTTP/3还在普及中,但前景很光明。
第八章:HTTP的实际应用
8.1 RESTful API
REST(Representational State Transfer)是一种设计风格,充分利用了HTTP的特性。
RESTful API的原则:
- 资源导向:一切都是资源,用URI标识
- 使用HTTP方法:GET获取,POST创建,PUT更新,DELETE删除
- 无状态:每个请求包含所有必要信息
- 统一接口:一致的接口设计
举个例子,一个博客的RESTful API可能是这样的:
GET /articles # 获取所有文章列表
GET /articles/123 # 获取ID为123的文章
POST /articles # 创建新文章
PUT /articles/123 # 更新ID为123的文章
DELETE /articles/123 # 删除ID为123的文章
简洁、直观、符合HTTP语义。
8.2 Cookie和Session
由于HTTP是无状态的,我们需要其他机制来跟踪用户。
Cookie:服务器在响应中发送Set-Cookie头,浏览器保存Cookie,在后续请求中自动发送。
Set-Cookie: session_id=abc123; HttpOnly; Secure
参数说明:
HttpOnly:JavaScript无法访问,防止XSS攻击Secure:只在HTTPS连接中发送SameSite:限制第三方Cookie,防止CSRF攻击
Session:服务器端保存的用户状态。通常的做法是用Cookie存储一个session ID,服务器根据这个ID查找对应的Session数据。
8.3 缓存
缓存可以显著提高性能,减少服务器负载。HTTP提供了丰富的缓存机制。

强缓存:浏览器直接使用缓存,不向服务器发送请求。
控制头:
Cache-Control: max-age=3600:缓存3600秒Expires: Wed, 21 Oct 2026 07:28:00 GMT:缓存到指定时间
协商缓存:浏览器向服务器确认缓存是否还有效。
控制头:
ETag:资源的唯一标识(类似指纹)Last-Modified:资源最后修改时间
工作流程:
- 浏览器第一次请求,服务器返回资源和
ETag: "abc123" - 浏览器再次请求,发送
If-None-Match: "abc123" - 如果资源未变,服务器返回
304 Not Modified,浏览器使用缓存 - 如果资源变了,服务器返回
200 OK和新资源
8.4 内容协商
服务器可以根据客户端的能力和偏好返回不同版本的资源。
语言协商:
Accept-Language: zh-CN,en;q=0.8
服务器可以返回中文或英文版本。
格式协商:
Accept: application/json, text/html
API可能既支持JSON也支持HTML。
编码协商:
Accept-Encoding: gzip, deflate
服务器可以压缩响应以节省带宽。
8.5 断点续传
下载大文件时,如果网络中断,HTTP支持从中断处继续下载。
使用Range请求头:
Range: bytes=1024-2047
请求字节1024到2047。
服务器返回:
HTTP/1.1 206 Partial Content
Content-Range: bytes 1024-2047/10240
这样你就不需要重新下载整个文件了。
第九章:HTTP的安全性
9.1 常见的HTTP攻击
跨站脚本攻击(XSS) 攻击者在网页中注入恶意脚本,窃取用户信息。
防御:
- 对用户输入进行转义
- 使用
Content-Security-Policy头部 - Cookie设置
HttpOnly
跨站请求伪造(CSRF) 攻击者诱使用户在已登录的网站上执行非预期操作。
防御:
- 使用CSRF token
- 检查
Referer头 - Cookie设置
SameSite
SQL注入 攻击者通过构造特殊的输入,执行非预期的数据库查询。
防御:
- 使用参数化查询
- 对输入进行验证和清理
点击劫持 攻击者用透明的iframe覆盖在正常网页上,诱导用户点击。
防御:
- 使用
X-Frame-Options头部 - 使用
Content-Security-Policy的frame-ancestors指令
9.2 安全相关的HTTP头部
Strict-Transport-Security (HSTS)
Strict-Transport-Security: max-age=31536000; includeSubDomains
强制浏览器使用HTTPS。
Content-Security-Policy (CSP)
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'
控制页面可以加载哪些资源,防止XSS。
X-Content-Type-Options
X-Content-Type-Options: nosniff
防止浏览器猜测内容类型。
X-Frame-Options
X-Frame-Options: DENY
防止页面被嵌入iframe,防止点击劫持。
第十章:HTTP的未来
10.1 HTTP/3的普及
虽然HTTP/3已经标准化,但普及还需要时间。主要挑战:
- 需要服务器和客户端都支持
- 一些网络设备可能会阻止UDP流量
- 需要更新现有的基础设施
但趋势是明确的。主流浏览器和服务器都在积极支持。
10.2 WebSocket
虽然不是HTTP的一部分,但值得一提。WebSocket提供了全双工通信,适合实时应用(聊天、游戏、实时通知等)。
它从HTTP”升级”而来:
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
服务器同意后,连接就变成了WebSocket,可以双向实时通信。
10.3 HTTP/2 Server Push的反思
HTTP/2引入了服务器推送,但实践中发现效果不如预期:
- 很难准确判断客户端需要什么
- 可能推送客户端已经有的资源
- 增加了复杂性
HTTP/3虽然支持推送,但业界已经不太推荐使用了。取而代之的是更智能的预加载策略。
10.4 性能优化的新思路
103 Early Hints 一个新的状态码,允许服务器在最终响应之前,先发送提示,告诉浏览器可以开始预加载某些资源。
优先级 HTTP/2和HTTP/3都支持请求优先级,但实践中很多服务器没有正确实现。这是一个需要改进的领域。
边缘计算 越来越多的内容通过CDN和边缘节点提供,减少延迟。
结语:HTTP的本质
说了这么多,让我们回到最初的问题:HTTP到底是什么?
从技术角度,它是一个应用层协议,定义了客户端和服务器之间如何通信。
但从更深层次来说,HTTP是互联网的语言。它让全世界数十亿设备能够相互理解、相互交流。它是万维网的基础,是你每天享受互联网服务的幕后功臣。
HTTP的设计哲学是简单、灵活、可扩展。正因为如此,它才能从1989年的简陋原型,演变成今天支撑整个互联网的基础设施。
当你下次打开浏览器,输入网址,看到网页加载出来时,你知道背后发生了什么。你的浏览器和远方的服务器进行了一次优雅的对话,用的正是HTTP这种通用语言。
它可能不完美——没有什么技术是完美的——但它工作得很好,而且还在不断进化。从HTTP/1.0到HTTP/3,每一次演进都在解决实际问题,让互联网更快、更安全、更可靠。
作为普通用户,你不需要了解这些细节也能愉快地上网。但如果你是开发者,或者只是对技术感兴趣,理解HTTP会让你对互联网有更深的认识。你会知道为什么有些网站加载快,有些慢;为什么有时会看到404错误;为什么HTTPS很重要。
HTTP就像空气,我们每时每刻都在用它,但很少注意到它的存在。希望这篇文章让你对这个”看不见的基础设施”有了更深的了解和欣赏。
互联网的魅力就在于此:在看似简单的表面下,是无数精巧的技术在协同工作。HTTP就是这个美丽体系中不可或缺的一部分。
感谢你读到这里!如果你对HTTP还有什么疑问,或者想深入了解某个具体方面,欢迎继续探索。互联网的世界很大,HTTP只是一个开始。


发表回复