【计算机网络】HTTP协议核心知识梳理
文章目录
- 前言
- 一、HTTP特点
- 1.1 基于请求-响应模型
- 1.2 无状态
- 补充:会话机制
- 1.3 明文无加密
- 补充:HTTPS
- 二、HTTP工作流程
- 2.1 请求格式
- 2.1.1 请求行-Request Line
- 2.1.2 请求头-Request Headers
- 2.1.3 请求体-Request Body
- 2.2 响应格式
- 2.1.2 响应行-Response Line
- 2.2.3 响应头-Response Headers
- 2.2.4 响应体-Response Body
- 三、HTTP常见问题
- 3.1 跨域
- 3.2 缓存
前言
HTTP全称Hyper Text Transfer Protocol。直译就是超文本传输协议。这是一种指定了浏览器和服务器之间数据传输的规则(客户端发起请求、服务器返回响应),也是互联网的核心通信协议。像我们平常浏览网页,调用API接口都离不开HTTP协议。HTTP自身是基于TCP协议,为浏览器到服务器之间提供可靠、有序、面向连接的数据传输服务。
一、HTTP特点
1.1 基于请求-响应模型
对于HTTP协议而言,一次请求对应一次响应。并且它是一种单向模式
,既客户端主动发起请求,服务器被动返回响应。
每个请求都会被发送到一个服务器,它会处理这个请求并提供一个称作响应的回复。在客户端与服务器之间,还有许许多多的被称为代理的实体,履行不同的作用,例如充当网关或缓存。
1.2 无状态
在HTTP中,每一个请求-响应模型都是独立的。也就是说多次请求之间是不能共享数据,每一次请求的上下文都是独立的。
补充:会话机制
虽然HTTP本身是无状态的,但我们可以通过会话机制
,服务器为每个客户端创建一Session,这是一种键值对结构用于存储信息,并生成一个唯一的SessionID返回给客户端。客户端再此发起请求的时候,通过唯一SessionID匹配到服务器端上的建一Session,从而实现数据的共享,类似一种全局上下文。
1.3 明文无加密
对于HTTP协议来说,每一次浏览器发起的请求都是按照协议格式,将信息打包成一个HTTP请求包(请求行+请求头+请求体)。然后这一条数据包会经由路由器抵达运营商,再通过各种CDN转发,最后抵达目标服务器。这传输链路中的每一个环节都能查到真实HTTP请求包数据。HTTP协议本身是一个全明文传输的协议。
补充:HTTPS
HTTPS全称Hypertext Transfer Protocol Secure,它并非独立协议,而是通过SSL/TLS协议提供的安全连接进行的HTTP通信。考虑到HTTP的明文无加密,HTTPS是给我们的请求加密。
HTTPS的加密分两步。第一步通过非对称加密交换对称对称加密密钥
,第二步再通过对称加密密钥加密解密请求包。
非对称加密的方式是指使用一对密钥(公钥+私钥)来加密和解密。在HTTPS中,客户端拿到公钥后,会生成一个对称密钥,并用公钥来将这个对称密钥加密。服务器在通过私钥解密出对称密钥后,后续是数据包都用这个临时生成的对称密钥进行数据加密。
二、HTTP工作流程
当客户端想要和服务器通信时,进行信息交互时,过程表现为下面几步:
- 打开一个TCP连接:TCP连接被用来发送一条或多条请求,以及接受响应消息。客户端可能打开一条新的连接,或重用一个已经存在的连接,或者也可能开几个新的与服务器的TCP连接。
- 发送一个 HTTP 报文
- 读取服务端返回的报文信息
- 关闭连接或者为后续请求重用连接。
无论是请求还是响应,报文都是HTTP中的核心。下面分别以请求和响应来分别介绍其中的报文结构。
2.1 请求格式
一个请求报文分为三种部分:请求行,请求头和请求体(请求行和请求头是必须存在的,请求头可选一般是在客户端发起POST这样的方法里包含)。
2.1.1 请求行-Request Line
起始行的格式为:方法+URL+协议版本。表明请求的核心信息
标准HTTP方法
- GET
- 请求获取指定资源(如网页、图片等)。
- 参数通常附加在 URL 中,请求体为空;具有幂等性(多次请求结果一致)和安全性(不修改资源)。
- POST
- 向服务器提交数据,用于创建或修改资源(如表单提交、上传文件)。
- 数据放在请求体中,不暴露在 URL;非幂等(多次提交可能产生不同结果,如重复创建订单)。
- PUT
- 向指定资源位置上传最新内容,通常用于全量更新资源(若资源不存在则创建)。
- 幂等性(多次请求结果一致,最终资源状态相同)。
- PATCH
- 对资源进行部分更新(仅修改指定字段,而非全量替换)。
- 非幂等(若更新逻辑依赖当前状态,多次请求可能结果不同)。
- DELETE
- 请求服务器删除指定资源。
- 幂等性(多次删除同一资源,最终结果一致)。
- HEAD
- 与 GET 类似,但仅返回响应头(不包含响应体)。
- 常用于检查资源是否存在、获取资源元信息(如文件大小、修改时间)。
- OPTIONS
- 请求服务器支持的 HTTP 方法(跨域请求时,浏览器会先发送 OPTIONS 预检请求,验证是否允许跨域)。
- 响应中会包含 Allow 头部,列出服务器支持的方法。
- CONNECT
- 建立与目标服务器的隧道连接(通常用于 HTTPS 代理,如 CONNECT example.com:443 HTTP/1.1 表示通过代理访问 HTTPS 资源)。
- TRACE
- 回显服务器收到的请求,用于诊断或测试(验证请求是否被中间代理修改)。
- 可能泄露敏感信息,部分服务器禁用此方法。
2.1.2 请求头-Request Headers
请求头是多种键值对形式组成的集合,用来传递请求的一些附加信息。像我们用来实现接口鉴权的JWT,它就是通过键为“Authorization”,值为JWT字符串,放在Request Headers里作为验证信息附加在请求头里。
常用的请求头包括
请求头名称 | 作用描述 | 示例 |
---|---|---|
Host | 指定请求的服务器域名和端口(HTTP/1.1 必需) | 域名:端口 |
User-Agent | 标识客户端类型及版本信息 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) |
Accept | 告知服务器客户端可接受的响应数据格式(MIME 类型) | text/html,application/xhtml+xml,application/xml |
Accept-Encoding | 指定客户端支持的内容压缩算法(减少传输量) | gzip, deflate, br |
Accept-Language | 告知服务器客户端可接受的自然语言(用于国际化) | zh-CN,zh;q=0.9,en;q=0.8 |
Connection | 控制连接是否持久化(HTTP/1.1 默认 keep-alive) | Connection: keep-alive 或 Connection: close |
Content-Type | 仅用于带请求体的方法(POST/PUT 等) | 指定请求体数据格式 application/json、multipart/form-data、application/x-www-form-urlencoded |
Content-Length | 指定请求体的字节长度(服务器用于判断请求是否完整) | Content-Length: 1024 |
Authorization | 携带身份认证信息(如JWT) | ’ Bearer ’ + JWT |
Cookie | 携带客户端存储的Cookie数据(比如身份识别的sessionid) | sessionId=araby |
Referer | 标识当前请求的来源页面 URL(防盗链、统计来源) | Referer: https://www.google.com/search?q=example |
Origin | 跨域请求中标识源站(协议 + 域名 + 端口,不含路径) | Origin: https://www.example.com |
Cache-Control | 指定客户端缓存策略(如是否缓存、有效期) | no-cache、no-store、max-age=3600 |
2.1.3 请求体-Request Body
请求格式中,只有部分HTTP方法中存在请求体,诸如POST,PUT和PATCH。并且请求体的格式根据请求头中的Content-Type来决定。常见的请求体格式有四种—— JSON、Form Data、x-www-form-urlencoded和XML。
- JSON【application/json】
- JSON是支持直接作为请求体传入到服务器,格式和我们日常使用的JSON一致。我们将一些待传输的数据序列化为JSON后写入请求体,请求头的Content-Type要设置为application/json,这样就能直接传入JSON
- Form Data 【multipart/form-data】
- Form Data一般是用来上次文件之类的,比方说上次含数据的Excel附件。格式类似于:文件名=[文件二进制流]。请求头的Content-Type要设置为multipart/form-data
- x-www-form-urlencoded【application/x-www-form-urlencoded】
- x-www-form-urlencoded是用于将表单数据转换为URL可传输的格式,也是我们常见的默认表单提交格式。数据转换为“键=值”的字符串,多个数据通过“&”连接。请求头的Content-Type要设置为x-www-form-urlencoded
- XML 【application/xml】
- XML类似JSON,也是一种数据格式。通过请求头的Content-Type要设置为application/xml,这样就能直接传入XML。
2.2 响应格式
一个响应报文也是分为三种部分:响应行,响应头和响应体(响应体取决于是客户端发起的请求是否要响应数据)。
2.1.2 响应行-Response Line
响应行的格式为:HTTP协议+状态码+状态信息。是响应格式里的核心信息。
像常见的200,404,500都属于状态码,是一个描述信息的编码,一共分为五类
类别 | 范围 | 含义 | 常见状态码及说明 |
---|---|---|---|
1xx | 100-199 | 信息提示 | 100 Continue:客户端需继续发送消息体(如POST大文件前的预检) |
2xx | 200-299 | 成功 | 200 OK:请求成功(如网页正常返回);204 No Content:请求成功但无消息体(如 DELETE) |
3xx | 300-399 | 重定向 | 301 永久重定向(如域名变更,浏览器会缓存);302 临时重定向(如临时跳转登录页) |
4xx | 400-499 | 客户端错误 | 400 Bad Request:请求参数错误;403 Forbidden:权限不足(如访问未登录页面);404 Not Found:资源不存在(如 URL 输错) |
5xx | 500-599 | 服务器错误 | 500 Internal Server Error:服务器内部错误;503 Service Unavailable:服务器繁忙(如流量超限) |
2.2.3 响应头-Response Headers
响应头和请求头类似,也是一组键值对形式组成的集合。比起请求头中告诉服务器的附加信息,响应头是包含一组要告诉客户端(浏览器)的基本信息。像常见的:
- Content-Type:最基础的头,定义响应体的数据格式(如image/jpeg表示图片、application/json表示接口数据)。
- Cache-Control:控制缓存的核心头,取值包括no-cache(不缓存)、max-age=秒数(缓存有效期)等。
- Set-Cookie:服务器向浏览器写入 Cookie 的指令,比如登录后返回Set-Cookie: sessionId=abc123,后续请求会自动携带该 Cookie。
- Access-Control-Allow-Origin:跨域专用头,指定允许访问的域名,如https://xxx.com或*(允许所有)。
2.2.4 响应体-Response Body
响应体里便是服务器实际返回的数据,比方说HTML,JSON数据。这些格式都会由响应头里的Content-Type体现。
三、HTTP常见问题
3.1 跨域
浏览器的中有个同源策略(Same-Origin Policy),既只有当两个网页的协议、域名、端口号三者完全一致时,才被视为 “同源”,浏览器才允许它们之间进行数据交互。否则的话浏览器就会拦截这次请求。像目前流行的前后端分离开发,前端网页接口和后端数据接口都是独立分开的,这就涉及到跨域的问题。
解决办法是我们在服务器响应的时候告诉浏览器这请求要允许跨域。浏览器会检查响应头中是否包含允许当前域名访问的信息(如Access-Control-Allow-Origin),如果当前发起请求的客户端域名包含在请求头设置的允许通行里,这前端正常使用该请求。
跨域核心的响应头
- Access-Control-Allow-Origin:指定允许跨域请求的域名,如指定的前端地址,或用*允许所有域名(不支持带Cookie的请求)。
- Access-Control-Allow-Methods:允许的请求方法,如GET, POST, PUT,解决 “预检请求(OPTIONS)” 的方法限制。
- Access-Control-Allow-Headers:允许的自定义请求头,如Content-Type, Token,解决带特殊头的跨域请求被拦截问题。
3.2 缓存
HTTP本身是支持保存服务器返回的资源缓存后,给后续相同请求直接使用。通过Cache-Control来操作,一个Cache-Control里可包含多个配置。比方说max-age=过期秒数,允许任何缓存的public,和仅允许客户端浏览器缓存的private。
值得注意的是Cache-Control有两个非缓存的设置no-cache和no-store。对于no-cache,缓存可以存储资源,但浏览器在使用前必须向服务器验证资源是否更新了;对于no-store则是完全禁止缓存。
no-cache的生效依赖于客户端保存资源的资源的最后修改时间和资源内容的哈希值。其步骤如下
- 当资源标记为no-cache时,浏览器不会直接用缓存,而是自动在请求头中带上If-Modified-Since(上次修改时间)或If-None-Match(资源哈希),发给服务器。
- 服务器收到请求后,会自动提取请求头中的If-Modified-Since或If-None-Match。
- 服务器自动用这些信息,对比当前资源的最新状态,判断后,服务器自动返回304(未变)或200(已变)
- 客户端收到服务器响应后,浏览器自动判断 —— 若返回304就用缓存,若返回200就更新缓存并使用新资源