Appearance
SpringMVC教程 - 3 HTTP协议介绍
下面简单介绍一下 HTTP 协议的一些内容,帮助我们理解 HTTP 发送数据和返回数据的格式。
HTTP 协议包括请求协议和响应协议,也就是规定了请求服务器的数据格式、服务器返回的数据格式。
我们使用最多的发起 HTTP 的方式,就是通过浏览器浏览网页,打开浏览器的开发者工具,我们可以看到每个请求的详细信息。
举个栗子:

下面我们就来详细介绍一下 HTTP 请求协议的格式。
3.1 请求协议
我们在发起网络请求的时候,请求的格式大概如下:
http
POST /users HTTP/1.1 ← ① 请求行
Host: example.com ← ② 请求头,下面多行都是
Content-Type: application/json
Content-Length: 47
← ③ 空白行
{"username": "foooor", "password": "123456"} ← ④ 请求体内容分为下面四个部分:
- 请求行(
POST /users HTTP/1.1) - 请求头(
Content-Type等),请求头有很多,是key-value形式; - 空白行,Header 与 Body 之间的分隔符;
- 请求体(
{"username": "foooor", "password": "123456"}),请求体有不同的格式,请求体的格式 是由请求头中的Content-Type指定的。
3.2 响应协议
当浏览器或客户端发送请求到服务器后,服务器会返回响应,响应的格式与请求类似,也分为几个部分:
http
HTTP/1.1 200 OK ← ① 响应行
Content-Type: application/json; charset=utf-8 ← ② 响应头(下面多行都是 key-value 形式)
Content-Length: 35
Server: Apache/2.4.41 (Ubuntu)
← ③ 空白行
{"message": "User created", "id": 1} ← ④ 响应体响应也分为下面四个部分:
- 响应行(
HTTP/1.1 200 OK):包含协议版本、状态码、状态描述。 - 响应头:如
Content-Type、Server、Set-Cookie等,用来说明返回信息的格式、长度、服务器信息等。 - 空白行:用于分隔响应头和响应体。
- 响应体:服务器返回的真实数据,可能是 JSON、HTML、文件等。
常见状态码:
| 状态码 | 描述 |
|---|---|
200 OK | 请求成功 |
201 Created | 创建资源成功 |
400 Bad Request | 请求参数错误 |
401 Unauthorized | 未授权 |
404 Not Found | 资源不存在 |
500 Internal Server Error | 服务器错误 |
3.3 请求方法
我们请求服务器最常用的两种方法就是 Get 请求和 Post 请求:
- GET 用于从服务器获取资源,一般用于读操作;
- POST 用于向服务器提交数据(如表单、JSON),一般用于写操作。
通过浏览器地址栏像服务器发送请求,只能发送 Get 请求,如果想发起 Post 请求,只能使用 Form 表单、JavaScript 或者一些第三方的工具(例如 Postman、Apifox )。
Get 请求和 Post 请求的主要区别如下:
| 特性 | GET | POST |
|---|---|---|
| 参数位置 | 参数是拼接在 URL 后面的,例如 http://www.foooor.com?userId=123&username=doubi (userId和username是参数) | 放在请求体中(Request Body) |
| 参数长度 | 受URL长度限制(不同浏览器限制不同,约2KB-8KB) | 理论上无限制(实际受服务器配置限制) |
| 数据可见性 | 明文暴露在URL中,可被浏览器历史、日志记录 | 相对安全,参数在请求体内,不可见 |
| 书签/分享 | 可被收藏为书签,URL包含所有参数 | 无法直接收藏 |
| 缓存 | 可被缓存(浏览器、CDN等) | 默认不可缓存 |
| 幂等性 | 多次请求结果相同(使用Get请求不应修改数据) | 非幂等:多次提交可能导致重复数据 |
HTTP 其实定义了很多请求方法,用来告诉服务器你想对资源做什么。我们常用的是 GET、POST、PUT、DELETE,还有 HEAD、PATCH、OPTIONS 等。比如 HEAD 和 GET 很像,但它只返回响应头,常用来检查资源是否存在;其他方法知道有这个方法就可以了。
从 协议层面 来说,GET 和 DELETE 请求都是可以带请求体的,POST、PUT 也都可以带 URL 参数,协议本身没有做限制。只是多数浏览器和后端框架为了保持一致性,默认不会处理 GET 和 DELETE 的请求体,所以这两个方法的参数一般都会写在 URL 上;而 POST、PUT 这样的请求才会把数据放在请求体里传给服务器。
不管 GET 还是 POST,它们最终都是通过 同一个 TCP 连接 发出去的。一般来说,GET 会一次性把请求发送完;而 POST 有时候会拆成两步(先发 header,拿到服务器的 100 Continue 后再发 body),不过这只是浏览器的优化方式,不是协议规定。
3.4 常见的请求体格式
在发起和响应请求的时候,都会传递 MIME 类型,用来标识请求的消息体和响应的消息体的格式。在 HTTP 协议中,会在请求头和响应头中添加 Content-Type 来标识 MIME 类型。
也就是说在 HTTP 协议中,请求(Request)和响应(Response)都会使用 Content-Type :
- 在请求中,当浏览器或客户端发送数据给服务器时,需要通过
Content-Type告诉服务器 请求体是什么格式,这样服务器才能正确解析。 - 在响应中,服务器返回数据时,也必须通过
Content-Type告诉浏览器 响应体是什么格式,浏览器会根据不同的Content-Type进行展示或处理响应体。
而 POST 和 PUT 请求的参数都是放在请求体中的。请求体的格式 是由请求头中的 Content-Type 指定的,下面来介绍一下常用的请求体。
1 application/x-www-form-urlencoded
这是 HTML <form> 表单的默认提交方式。
举个栗子:
http
POST /login HTTP/1.1 ← ① 请求行
Content-Type: application/x-www-form-urlencoded ← ② 请求头
← ③ 空白行
username=foooor&password=123456 ← ④ 请求体特点:
- 键值对形式,使用
&连接。 - 与 URL 查询参数(
?username=kang&password=123456)几乎相同。 - 在服务端(比如 Java Servlet、Spring、Express)中,框架能自动解析成参数对象。
2 multipart/form-data
可以用于 上传文件 或 提交二进制数据 的表单。
举个栗子:
http
POST /upload HTTP/1.1 ← ① 请求行
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryabc123 ← ② 请求头
← ③ 空白行
------WebKitFormBoundaryabc123 ← ④ 分隔符,表示一个新的字段开始
Content-Disposition: form-data; name="username" ← ④ 这一个字段的信息,例如字段名称
foooor ← ④ 字段的实际值
------WebKitFormBoundaryabc123 ← ④ 分隔符,表示一个新的字段开始
Content-Disposition: form-data; name="file"; filename="avatar.png" ← ④ 字段信息
Content-Type: image/png ← ④ 字段信息
← ③ 空白行
(binary data) ← ④ 文件的二进制内容
------WebKitFormBoundaryabc123-- ← ④ 结束标志,--表示整个表单的结束特点:
- 请求体可以包含多个独立的字段,每个字段都有独立的边界(
boundary),字段可以包含文本字段和文件。 - 最后面的 两个连字符
--表示整个表单的结束,没有这两个--,服务器会认为数据还没传完。
浏览器上传文件时通常使用这种格式,我们除了可以传递文件,同时还可以传递其他的信息。
3 application/json
用于提交 JSON 格式的数据,对于现在前后端分离的项目,一般采用这种格式提交和返回数据,我们可以封装 JSON 格式的数据,作为请求体,发送给服务器。
举个栗子:
http
POST /api/user HTTP/1.1 ← ① 请求行
Content-Type: application/json ← ② 请求头
← ③ 空白行
{"username": "foooor", "password": "123456"} ← ④ 请求体,是JSON字符串特点:
- 常用于前后端分离的 Web 项目(前端用
fetch/axios发起请求)。 - 服务端解析 JSON 数据后再转换为对象。
4 其他比较少用的类型
| Content-Type | 用途 |
|---|---|
text/plain | 纯文本数据 |
application/xml | XML 格式数据(SOAP、旧系统常用) |
application/octet-stream | 二进制数据流(下载或上传文件时),整个请求体就是文件件的二进制内容,没有文件名、字段名等信息。 |
通过上面的介绍,可以让我们知道怎么在发起请求的时候传递数据。
3.5 常见的响应体格式
而服务器在响应时,常用的 Content-Type 类型如下:
1 text/html
用于返回 HTML 页面,浏览器会按照网页渲染。
举个栗子,服务器返回:
http
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
<h1>Hello SpringMVC</h1>- 浏览器会把
<h1>Hello SpringMVC</h1>当作网页渲染,而不是普通文本。 - 常用于传统 Web 项目中返回 Thymeleaf、JSP 页面等,浏览器会渲染为网页。
2 application/json
用于返回 JSON 数据,前后端分离项目中一般都使用这个,application/json 可以用于请求和可以用于响应。
http
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{"message": "success", "username": "foooor"}- 前端使用
fetch、axios、XMLHttpRequest等发起 AJAX 请求时,通常使用 JSON 作为响应体。
- 服务器在返回数据是,需要用 JSON 序列化框架(如 Spring 的 Jackson)将对象转换成 JSON,然后返回。
3 text/plain
表示返回 纯文本。
http
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
OK- 只返回字符串,不带格式。
- 在调试接口、返回简单文本消息时常用。
4 application/octet-stream
表示返回 二进制数据流,比如下载文件。
举个栗子,告诉浏览器这是一个二进制文件:
http
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="report.pdf"- 浏览器不会解析内容,只会弹出下载。
Content-Disposition决定是否下载以及文件名。
5 image/png等
如果返回图片,会使用图片对应的 Content-Type,例如:
http
HTTP/1.1 200 OK
Content-Type: image/png- 浏览器会自动显示图片,
- 常用于验证码、头像图像接口等。
3.6 通过Apifox发起HTTP请求
除了通过浏览器发起请求,我们还可以使用工具,常用的有 Postman 和 Apifox。
以下以 Apifox 为例,发起请求。
首先新建一个项目:

然后就可以在项目下创建访问接口,可以输入请求地址,选择请求方法,还可以添加请求头、请求参数、和请求体等信息:

点击发送按钮,就可以发起请求,并在下面得到响应结果。