实际上,HTTP 就是基于请求响应的模式来完成通信的,即每次通信都是由客户端发送请求,服务器收到请求之后,根据请求进行处理,然后将数据相应给客户端,这就完成了一次通信。
HTTP 协议有以下规定
- 每次请求响应都是独立的,相互之间互不干扰,这种模式我们也称为无状态协议
- 每次请求响应传递的消息都必须是字符串(纯文本),而且字符串的格式必须按照 HTTP 规定的格式来书写。
https 实际上就是更加安全的 http 协议
既然响应和请求都要按照 HTTP 规定的格式,那 HTTP 规定了什么格式呢?
HTTP 规定请求的格式如下:

显然,一次请求虽然是一个字符串,但也包含了三个部分,分别是请求行,请求头,请求体,我们从这也能看出他的规则,首先,请求行只有一行,请求行和请求头是用过一个换行符进行分割,请求头又可以有很多项,每一项通过一个换行分割,请求头和请求体通过两个换行分割,这就构成了一个 HTTP 请求所要求的格式。
- 请求行:告诉客户端我想要干什么
- 请求头:描述本次请求和业务本身无关的一些额外信息
- 请求体:存放必要的业务信息,一次请求是可以没有请求体的,但请求行和请求头必须要有
这几个概念比较抽象,现在看不懂是很正常的,读者需要在以后的学习中不断加深对齐理解。
这里以上面的例子介绍请求行,请求头,请求体是干什么的
首先,在上面的例子中,POST /api/user/login HTTP/1.1 这个就是请求行,很显然,请求行里面包含三个部分,分别是 POST, /api/user/login, HTTP/1.1 这三个部分,其中 POST 为请求方法,/api/user/login 就是我们本次请求 URL 地址中的路径+参数+哈希,HTTP/1.1 就是协议和版本,由于我们是学习前端,所以对于 HTTP 请求的版本我们不涉及。而对于 URL 地址中的路径+参数+哈希,这也很好理解,当我们要给这个服务器发送一个请求的时候,我们一定是已经找到这个服务器了,所以我们就没必要再把 URL 地址中的服务器地址和后面的端口号再传过去,我们只需要将服务器地址后面的路径,参数,哈希传过去即可。
我们主要关注第一个,也就是请求方法,请求方法就是一个单词,表示了我这次请求想要干什么,请求方法主要有以下几个
| 序号 | 方法 | 描述 |
|---|---|---|
| 1 | GET | 用于请求服务器发送某个资源。GET 请求不应该对服务器上的资源做出任何更改,并且应该是幂等的(即多次重复的请求应该产生相同的结果)。例如,当你在浏览器中输入 URL 地址时,浏览器会发送一个 GET 请求来获取该 URL 对应的网页。 |
| 2 | HEAD | 类类似于 GET 请求,但服务器不返回请求的资源主体,只返回响应头。HEAD 请求通常用于获取资源的元信息,如资源的大小、类型等,而不需要获取资源的实际内容。 |
| 3 | POST | 用于向服务器提交数据,通常用于提交表单或上传文件。POST 请求可能会导致服务器上的状态更改,并且不一定是幂等的。例如,在提交注册表单时,浏览器通常会发送一个 POST 请求,将用户提供的信息发送到服务器进行处理。 |
| 4 | PUT | 用于向服务器上传资源,通常用于更新已存在的资源或创建新的资源。PUT 请求应该是幂等的,即多次执行相同的 PUT 请求应该产生相同的结果。 |
| 5 | DELETE | 用于请求服务器删除指定的资源。DELETE 请求应该是幂等的,即多次执行相同的 DELETE 请求应该产生相同的结果。 |
| 6 | CONNECT | 用于建立到服务器上指定端口的隧道,通常用于代理服务器。 |
| 7 | OPTIONS | 用于请求服务器返回支持的 HTTP 方法和其他选项。例如,客户端可以发送 OPTIONS 请求来确定服务器支持哪些 CORS(跨域资源共享)策略。 |
| 8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
| 9 | PATCH | 用于在请求-响应链上的每个节点获取传输路径。TRACE 请求通常用于调试和测试,以查看请求在经过各种代理服务器和中间件时如何被修改。 |
我们比较常用的是以下四个
- GET:获取
- DELETE:删除
- POST:提交
- PUT:更新(修改)
上面四个方法可以囊括增删改查四个场景,作为一个前端开发者,了解者四个方法即可,如果我们要获取一个数据,就用 GET 方法,如果我们要提交一个数据,就用 POST 方法,如果我们要删除一个数据,就是用 DELETE 方法,如果我们要修改一个数据,就是用 PUT 方法。这里一个一个举例,例如我这里有一个电商网站,我要登录,实际上就是一个提交用户的账号和密码的操作,就要使用 POST 请求,登录后我要查看我的购物车,这是一个获取操作,就使用 GET 请求,我要将我的购物车中的一件商品删除,这就要用 DELETE 请求,此时我看上了一个商品,要把他加到购物车,注意,这个使用的应该是 POST 请求,而如果我要修改我购物车内某个商品的数量,就是要给更新操作,就使用 PUT 请求。
从语义化的角度来看,GET 请求和 DELETE 请求一般是不包含请求体的,POST 请求可以用来上传数据,比如登录的账号密码,上传文件,这些都要使用 POST 请求,而 PUT 请求则需要提交修改的数据,而 DELETE 请求和 GET 请求一般都不应该包含请求体。有的读者可能有疑问,如果我要删除我的购物车,那起码要让服务器知道要删除的是我的购物车,而不是别人的购物车对吧,也就是说要把我的身份信息传递进去,这些身份信息一般被包含在请求头里。
由于 GET 和 DELETE 请求没有请求体,我们如果需要传递数据,只有两种解决方案,其一是将数据放到 URL 的参数中,其二就是使用动态路由。我们通过浏览器访问一个网页,实际上就是向服务器发送了一个 GET 请求,获取到了该网站的 HTML 文件信息。
接下来是请求头,请求头包含的所有内容均为键值对,格式为 键:值,多个键值对使用换行来分割,主要包含了和请求业务本身无关的额外信息,比如我发出请求的服务器是哪一个,比如我请求体的格式是什么,实际上,浏览器在发送请求的时候自动就会给你带上一大堆请求头,这些请求头信息在大多数场景下都用不到,但偶尔也会用到,所以如果真的服务器需要用,也可以拿到这些信息,以下是浏览器自动附带的一些信息
- Host:url 地址中的主机
- User-Agent:客户端的信息描述
- Content-Type: 请求体的消息是什么格式,如果没有请求体,这个字段无意义
而请求体就是具体内容,GET 请求和 DELETE 请求一般是不附带请求体的,请求体的格式必须和 Content-Type 中指定的格式一致,否则可能导致服务器无法识别。至于请求体的具体内容,我们需要查看接口文档。
接下来是响应的内容,响应也可以分为响应行,响应头,响应体,如下所示

可见,这和请求非常类似,响应行中也可以分为两部分,分别为 HTTP 版本,响应的状态码+状态消息,这里的状态码要单独介绍一下,就是服务器收到我们的请求之后,可能会有一些不同的结果,比如用户尝试获取一个不存在的资源,我服务器找不到,这个时候就必须要告诉客户端这个出错了,这种消息就是通过响应行告诉客户端的,我们可以将状态码看做服务器对当前请求的一种态度,客户端可以通过这个状态码判断本次请求是否成功。
状态消息通常就是状态码的一种更加友好的表达,比如我们看到 200 可能不知道是什么意思,但是如果看到 OK,就很清楚本次请求是成功的
关于状态码,这里会出现很多情况,如下所示:
| 分类 | 分类描述 |
|---|---|
| 1** | 信息,服务器收到请求,需要请求者继续执行操作 |
| 2** | 成功,操作被成功接收并处理 |
| 3** | 重定向,需要进一步的操作以完成请求 |
| 4** | 客户端错误,请求包含语法错误或无法完成请求 |
| 5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
以上为状态码的分类,接下来是一些常见的状态码:
- 200 OK:一切正常。
- 301 Moved Permanently:资源已被永久重定向。
你的请求我收到了,但是呢,你要的东西不在这个地址了,我已经永远的把它移动到了一个新的地址,麻烦你取请求新的地址,地址我放到了响应头的Location中了 - 302 Found:资源已被临时重定向。
你的请求我收到了,但是呢,你要的东西不在这个地址了,我临时的把它移动到了一个新的地址,麻烦你取请求新的地址,地址我放到了请求头的Location中了 - 304 Not Modified:文档内容未被修改。
你的请求我收到了,你要的东西跟之前是一样的,没有任何的变化,所以我就不给你结果了,你自己就用以前的吧。啥?你没有缓存以前的内容,关我啥事 - 400 Bad Request:语义有误,当前请求无法被服务器理解。
你给我发的是个啥啊,我听都听不懂 - 403 Forbidden:服务器拒绝执行。
你的请求我已收到,但是我就是不给你东西 - 404 Not Found:资源不存在。
你的请求我收到了,但我没有你要的东西 - 500 Internal Server Error:服务器内部错误。
你的请求我已收到,但这道题我不会,解不出来,先睡了
关于 301 和 302 的区别,一个是永久重定向,一个是临时重定向,当浏览器在请求一个 URL 的时候,如果返回 301,那么表示已经被永久重定向,此时浏览器会直接将新地址进行缓存,下次访问该地址的时候就会直接使用缓存内的新地址而不发送请求,而临时重定向由于是临时的,所以浏览器不会进行缓存。
响应头也是由键值对组成的,其中响应头中也有一个叫 Content-Type 的响应头,表示响应体的格式。响应体则表示响应的主体内容。
实际上,当我们在浏览器请求一个图片的时候,浏览器会直接打开这张图片,这就是由于浏览器识别到了响应体的
Content-Type,发现这是一张图片,所以就会按照图片来展示。