协议演进

HTTP(HyperText Transfer Protocol,超文本传输协议)是万维网数据通信的基础协议,由蒂姆·伯纳斯-李于1989年在欧洲核子研究中心(CERN)提出。它采用客户端-服务器架构,通过请求-响应模式在客户端(通常是浏览器)与服务器之间传输超文本资源。

HTTP/0.9是最初的版本,仅支持GET方法,没有首部字段,响应只能是HTML文本。HTTP/1.0(1996年)引入了POST和HEAD方法、状态码、首部字段、版本号,支持多媒体类型(通过MIME类型),但每次请求都需要建立新的TCP连接(非持久连接)。HTTP/1.1(1997年)是目前最广泛使用的版本,引入了持久连接(Keep-Alive)、管道化(Pipelining,允许连续发送多个请求而无需等待响应)、分块传输编码(Chunked Transfer Encoding)、缓存控制机制、Host首部(支持虚拟主机)和更多的方法(PUT、DELETE、OPTIONS、TRACE、CONNECT)。

HTTP/2(2015年)是二进制协议(而非HTTP/1.x的文本协议),引入了多路复用(Multiplexing,在单一TCP连接上并行传输多个请求和响应,解决了队头阻塞问题)、头部压缩(HPACK算法,减少冗余首部传输)、服务器推送(Server Push,服务器可以主动向客户端推送资源)和流优先级(Stream Priority,允许客户端指定请求的优先级)。HTTP/2仍基于TCP,因此受到TCP层队头阻塞的影响。

HTTP/3(2022年)基于QUIC协议(Quick UDP Internet Connections),使用UDP而非TCP作为传输层协议。QUIC集成了TLS 1.3加密,提供0-RTT(零往返时间)连接建立,消除了TCP和TLS握手带来的延迟。QUIC的连接迁移特性使网络切换(如从WiFi切换到移动数据)时连接不会中断。HTTP/3的多路复用完全避免了队头阻塞,因为每个流独立传输,一个流的丢包不会影响其他流。

报文结构

HTTP报文是文本格式的(HTTP/2和HTTP/3在传输时转为二进制,但语义层面仍保持文本概念),分为请求报文和响应报文两种类型。请求报文由请求行(Request Line)、请求首部(Request Headers)和请求主体(Request Body,可选)组成。响应报文由状态行(Status Line)、响应首部(Response Headers)和响应主体(Response Body,可选)组成。首部与主体之间以空行(CRLF)分隔。

请求行的格式为:Method SP Request-URI SP HTTP-Version CRLF。例如:GET /index.html HTTP/1.1。Method表示请求方法,Request-URI表示请求的资源路径(可以是绝对路径或完整URL),HTTP-Version表示使用的HTTP版本。SP表示空格,CRLF表示回车换行。

状态行的格式为:HTTP-Version SP Status-Code SP Reason-Phrase CRLF。例如:HTTP/1.1 200 OK。Status-Code是三位数字的状态码,Reason-Phrase是对状态码的文本描述。状态码的第一位数字表示响应类别:1xx(信息性)、2xx(成功)、3xx(重定向)、4xx(客户端错误)、5xx(服务器错误)。

HTTP/1.1的持久连接通过Connection: keep-alive首部(HTTP/1.1默认持久连接,无需显式声明)实现。管道化允许客户端在收到前一个响应前发送多个请求,但服务器必须按请求顺序返回响应,这导致了队头阻塞(Head-of-Line Blocking)问题——如果第一个请求处理缓慢,后续请求的响应也会被阻塞。HTTP/2通过帧(Frame)和流(Stream)机制彻底解决了这个问题。

方法与状态码

HTTP方法(Method)定义了请求对资源执行的操作类型。GET方法请求指定的资源,是幂等且安全的(不应对服务器状态产生副作用)。POST方法向指定资源提交数据,通常用于表单提交或创建新资源,非幂等。PUT方法用于完整更新资源,幂等(多次执行结果相同)。PATCH方法用于部分更新资源。DELETE方法用于删除资源,幂等。HEAD方法类似于GET,但服务器不返回响应主体,仅返回首部,常用于检查资源是否存在或获取元信息。OPTIONS方法用于获取资源支持的HTTP方法(CORS预检请求使用此方法)。TRACE方法用于回显服务器收到的请求,主要用于诊断。CONNECT方法用于建立网络隧道(常用于HTTPS代理)。

幂等性(Idempotency)和安全(Safety)是HTTP方法的重要属性。安全方法不会改变服务器状态(GET、HEAD、OPTIONS、TRACE)。幂等方法多次执行产生的效果与一次执行相同(GET、HEAD、PUT、DELETE、OPTIONS、TRACE)。POST和PATCH通常既不是安全的也不是幂等的。

状态码是服务器对请求的响应状态的数字表示。常见的2xx状态码:200 OK(请求成功)、201 Created(资源创建成功)、204 No Content(请求成功但无返回内容)。常见的3xx状态码:301 Moved Permanently(永久重定向,搜索引擎应更新URL)、302 Found(临时重定向)、304 Not Modified(资源未修改,客户端可使用缓存)。常见的4xx状态码:400 Bad Request(请求格式错误)、401 Unauthorized(未认证)、403 Forbidden(无权限)、404 Not Found(资源不存在)、405 Method Not Allowed(方法不允许)、409 Conflict(资源冲突)、429 Too Many Requests(请求过于频繁)。常见的5xx状态码:500 Internal Server Error(服务器内部错误)、502 Bad Gateway(网关错误)、503 Service Unavailable(服务不可用)、504 Gateway Timeout(网关超时)。

首部字段

HTTP首部字段(Header Fields)是传递附加信息的键值对,分为通用首部、请求首部、响应首部和实体首部。通用首部适用于请求和响应,如Cache-Control(缓存策略)、Connection(连接管理)、Date(消息创建时间)。请求首部仅出现在请求中,如Host(目标主机和端口)、User-Agent(客户端信息)、Accept(可接受的MIME类型)、Accept-Language(可接受的自然语言)、Accept-Encoding(可接受的内容编码,如gzip、br)、Authorization(认证信息)、Referer(请求来源页面URL)。响应首部仅出现在响应中,如Server(服务器软件信息)、Location(重定向目标URL)、Set-Cookie(设置Cookie)。实体首部描述消息主体,如Content-Type(主体MIME类型)、Content-Length(主体长度,字节数)、Content-Encoding(主体内容编码)、Last-Modified(资源最后修改时间)、ETag(资源的实体标签,用于缓存验证)。

Content-Type首部指定了消息主体的媒体类型和字符编码,如text/html; charset=utf-8、application/json、multipart/form-data(用于文件上传)。在RESTful API中,application/json是最常用的内容类型。multipart/form-data用于包含文件的表单提交,消息主体被分割为多个部分,每个部分有自己的Content-Disposition和Content-Type首部。

CORS(Cross-Origin Resource Sharing,跨域资源共享)相关的首部是前端开发中频繁涉及的领域。浏览器的同源策略(Same-Origin Policy)限制了一个源的文档或脚本如何与另一个源的资源交互。两个URL的协议、主机和端口都相同才属于同源。CORS通过服务器返回的Access-Control-Allow-Origin等首部,允许服务器声明哪些源可以访问其资源。简单请求(GET/POST/HEAD,且首部在允许范围内)直接发送,浏览器自动处理CORS检查;非简单请求(如PUT、DELETE,或包含自定义首部的请求)会先发送预检请求(Preflight Request,OPTIONS方法),询问服务器是否允许该跨域请求。

缓存机制

HTTP缓存是提升Web性能的关键机制,它减少了网络传输延迟和服务器负载。缓存可以分为私有缓存(Private Cache,如浏览器缓存,仅供单个用户使用)和共享缓存(Shared Cache,如CDN、代理服务器缓存,可供多个用户使用)。

缓存控制通过Cache-Control首部实现,这是HTTP/1.1引入的最重要的缓存指令。常见指令包括:no-store(禁止任何缓存,每次都从服务器获取)、no-cache(可以缓存,但使用前必须向服务器验证资源是否过期)、max-age=<seconds>(资源在指定秒数内被视为新鲜,无需验证)、s-maxage=<seconds>(类似于max-age,但仅适用于共享缓存)、private(仅允许私有缓存)、public(允许任何缓存)、must-revalidate(缓存过期后必须向服务器验证,不能使用过期资源)。

缓存验证机制允许服务器在不传输完整资源的情况下确认缓存是否仍然有效。Last-Modified(响应首部,表示资源最后修改时间)与If-Modified-Since(请求首部,携带上次收到的Last-Modified值)是一对验证机制。ETag(响应首部,资源的唯一标识符,通常是内容的哈希值)与If-None-Match(请求首部,携带上次收到的ETag值)是另一对更精确的验证机制。当验证请求到达服务器时,如果资源未修改,服务器返回304 Not Modified,客户端继续使用缓存的副本;如果资源已修改,服务器返回200 OK和新的资源内容。

启发式缓存(Heuristic Caching)是在没有明确缓存指令时的默认行为。如果响应包含Last-Modified但没有Cache-Control,浏览器可能使用(LM - Date) * 0.1作为缓存有效期(其中LM是Last-Modified时间,Date是响应生成时间)。这种机制的不确定性使得显式设置Cache-Control成为最佳实践。

Cookie 与 Session

HTTP是无状态协议,服务器不会记住之前的请求。Cookie机制通过在客户端存储小型数据片段,使服务器能够识别和追踪用户。服务器通过Set-Cookie首部向客户端发送Cookie,客户端在后续请求的Cookie首部中自动携带这些Cookie。

Cookie的属性包括:Name和Value(Cookie的键值对);Domain(Cookie适用的域名,默认为当前主机,不包括子域);Path(Cookie适用的路径,默认为/);Expires(Cookie的过期时间,绝对时间)或Max-Age(Cookie的有效期,相对秒数);Secure(仅通过HTTPS传输);HttpOnly(禁止JavaScript通过document.cookie访问,防止XSS攻击窃取Cookie);SameSite(控制跨站请求时是否发送Cookie,Strict(仅同站请求发送)、Lax(部分跨站请求发送,如GET链接)、None(所有请求发送,需配合Secure))。

Session是服务器端维护用户状态的机制。当用户首次访问时,服务器创建一个唯一的Session ID,通过Cookie发送给客户端。客户端后续请求携带该Session ID,服务器根据ID查找对应的Session数据(存储在内存、数据库或缓存中)。Session数据可以存储复杂的用户状态信息,而Cookie仅存储Session ID,避免了在客户端存储敏感数据。

Token-Based Authentication(基于令牌的认证)是现代Web应用(尤其是SPA和移动应用)的主流认证方式。用户登录成功后,服务器签发一个JWT(JSON Web Token),包含用户身份信息和签名。客户端将Token存储在本地(localStorage或内存),后续请求通过Authorization: Bearer <token>首部携带Token。服务器验证Token的签名和有效期,无需查询数据库即可确认用户身份。JWT由Header(算法和类型)、Payload(声明数据)和Signature(签名)三部分组成,通过Base64Url编码和点号连接。

安全与 HTTPS

HTTPS(HTTP Secure)是HTTP over TLS/SSL的简称,通过加密层保护数据传输的安全性。TLS(Transport Layer Security,前身为SSL)提供三种安全服务:加密(防止窃听)、身份验证(防止冒充)和完整性保护(防止篡改)。

TLS握手过程(以TLS 1.2为例)包括:客户端发送Client Hello(支持的TLS版本、加密套件列表、随机数);服务器返回Server Hello(选定的TLS版本和加密套件、随机数)、证书(包含服务器的公钥和域名信息);客户端验证证书(检查证书链、有效期、域名匹配、吊销状态),生成预主密钥(Pre-Master Secret),用服务器公钥加密后发送;双方使用客户端随机数、服务器随机数和预主密钥生成会话密钥;后续通信使用会话密钥对称加密。TLS 1.3简化了握手过程,支持1-RTT甚至0-RTT恢复,移除了不安全的加密套件,提升了性能和安全性。

证书(Certificate)由证书颁发机构(CA,Certificate Authority)签发,包含服务器的公钥、域名、有效期、颁发者信息和数字签名。浏览器内置了受信任的CA根证书,用于验证服务器证书的真实性。Let's Encrypt是免费的自动化CA,通过ACME协议实现证书的自动申请和续期。自签名证书(Self-Signed Certificate)由自己生成,不被浏览器信任,仅适用于开发和内部环境。

常见的Web安全威胁包括:XSS(Cross-Site Scripting,跨站脚本攻击,攻击者注入恶意脚本到网页中,窃取用户Cookie或执行恶意操作,防御措施包括输入过滤、输出转义、CSP策略、HttpOnly Cookie);CSRF(Cross-Site Request Forgery,跨站请求伪造,攻击者诱导用户在已认证的网站上执行非自愿操作,防御措施包括CSRF Token、SameSite Cookie、Referer检查);SQL注入(通过输入注入SQL代码,防御措施是使用参数化查询);中间人攻击(窃听或篡改通信,防御措施是使用HTTPS和HSTS)。