1. http 协议的报文格式
http 是应用层协议,是浏览器和服务器之间的请求、响应的格式和规则。
- 请求报文格式
请求行(请求方法 + url + http版本号)
请求头
空行
请求体
- 响应报文格式
状态行(http版本号 + 状态码 + 原因短语)
响应头
空行
响应体
2. 九种请求方法
HTTP 定义了一组请求方法,表示要对url指定资源执行的操作。
http 1.0 定义了 3 种请求方法(前三),http 1.1 新增了 6 种(后六:删放选连+追踪修补)。
GET:请求指定资源。使用 get 的请求应该只用于获取数据。- 只获取数据:不会修改或增加数据、即不影响资源;
- 返回的数据在响应体中。get 请求体不包含数据。
HEAD:请求资源的头部信息,没有响应体。- 获取的头部信息是和 get 方法请求时返回的一致。
- 场景:下载文件前先获取其大小再决定是否要下载,以此可以节约带宽资源。
POST:发送数据给服务器。 数据包含在请求体中,请求体类型由Content-Type首部指定。- post 请求可能会创建新的资源或修改现有资源;
- 场景:提交表单、上传文件。
PUT:将数据发送到服务器以创建或者替换目标资源。- 和
POST区别在于,PUT方法是幂等的:调用一次和多次是等价的。而调用POST多次可能会有副作用,比如将一个订单重复提交多次。
- 和
DELETE:删除指定资源。OPTIONS:获取目标资源所支持的通信选项。- 预检请求:返回服务器针对某资源所支持的
http请求方法。
- 预检请求:返回服务器针对某资源所支持的
CONNECT:可以开启一个客户端和请求资源之间的双向沟通的通道。TRACE:回显服务器收到的请求,主要用于测试。PATCH:对资源进行部分修改,应用较少。
3. post 请求中 body 的四种数据格式
POST请求会在header中使用Content-Type字段声明 body 中的数据格式,以便让接收方知道怎么解析数据。
(1)application/x-www-form-urlencoded:是HTML默认的表单提交方式,Body 中的数据以 key1=value1&key2=value2的文本格式进行传输。
<form name="form" method="post">
<input type="text" name="key1" value="value1"/>
<input type="text" name="key2" value="value2"/>
</form>
header 中的 Content-Type 格式:
Content-Type: application/x-www-form-urlencoded
(2)multipart/form-data:body 中的数据允许由多部分组成,可以上传文件。(可以同时传递文本数据和二进制数据)
使用 HTML 表单提交时,需要在<form />标签内加上 enctype="multi.."
<form name="form" method="post" enctype="multipart/form-data">
<input type="file" id="file"/>
</form>
header 中的 Content-Type 格式会包含 boundary:
Content-Type: multipart/form-data; boundary=----WebKitFormBounda
body 中的多块数据也都是以 boundary 分隔的。
------WebKitFormBoundaryG4tAWTT3yikZt0WN
Content-Disposition: form-data; name="key1"
value1
------WebKitFormBoundaryG4tAWTT3yikZt0WN
Content-Disposition: form-data; name="key2"; filename="test.zip"
Content-Type: application/octet-stream
[文件二进制数据]
------WebKitFormBoundaryG4tAWTT3yikZt0WN--
(3)application/json:body 的内容就是 json 格式的文本,是接口最常用的格式。
发送时,仅需要在 header 中加上 Content-Type: application/json 即可。
(4)text/plain:body 的内容就只是纯文本。
发送时,仅需要在 header 中加上 Content-Type: text/plain 即可。
4. GET 和 POST 区别:两者本质上都是 TCP 连接
// GET
GET /index.html?age=20&height=170 HTTP/1.1
// POST
POST /index.html HTTP/1.1
Content-Type: application/x-www-form-urlencoded
age=20&height=170
-
参数的传递方式
- get 请求的参数通过 url 传递
- post 请求的参数放在请求体中
-
参数大小限制
- get 请求的参数有大小限制(2KB,因为 url 本身的限制)
- post 没有限制
-
安全性:因为 get 请求参数放在 url 中,所以不如 post。
-
主动缓存:get 请求浏览器会主动缓存,post 默认不会。
-
幂等:get 请求是幂等的,post 不是。
5. http 常用头部字段
建议先了解浏览器缓存。
-
通用头:请求头和响应头的通用头部。
cache-control(http1.1):用于控制缓存。- public:响应的所有内容都可以被客户端、代理服务器等任何对象缓存。
- private:默认值,只能被客户端缓存,不能被代理服务器缓存。
- no-cache:会缓存,但每次发请求时都需要用
ETag字段向服务器验证是否要使用缓存,如果缓存没变化则返回 304,继续使用缓存。 - no-store:禁止缓存。
- max-age=xxx:缓存内容将在 xxx 秒后失效。
Connection- keep-alive:默认持久连接。(使用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,不需要用新的)
- close:请求响应完成之后立即关闭连接。
-
请求头
【If-Modified-Since】:将Last-Modified的值发送给服务器,询问文件是否已经过期。过期则返回新资源,否则返回 304。【If-None-Match】:将ETag的值发送给服务器,询问文件是否过期。过期则返回新资源,否则 304。Host:服务器的域名。Referer:发起请求的页面的原始 url。Cookie:发送给服务端的 cookie 信息。Accept:告诉服务端,客户端接收什么类型的响应。Accept-Encoding:能正确接收的编码格式列表。User-Agent:告诉服务端,客户端使用的操作系统、浏览器版本和名称。
-
响应头
Location:需要将页面重定向的地址,一般状态码为 3xx 才有效。【ETag】:当前资源在服务器的唯一标识符。Set-Cookie
-
实体头:请求体和响应体使用的首部。
【Allow】:资源可支持的 http 请求方法。【Last-Modified】:资源的最后修改时间,精度不如ETag。因为只打开文件不修改,值也会变。【Expires】:响应过期时间。(http 1.0)Content-Type:客户端告诉服务器实际发送的数据类型。
6. http 不同版本的区别
1.0 版本
浏览器每次请求都需要与服务器建立一个 tcp 连接,完成请求后立即断开。
1.1 版本
-
默认长连接:
Connection: keep-alive。数据传输完成后保持 tcp 连接不断开,因此可以在一个 tcp 连接中发送多个 http 请求。
客户端不用等待上一次结果返回就可以发送下一次请求,但服务端必须按照接收到请求的顺序依次返回响应结果。
http 队头阻塞:若干请求排序串行处理,一旦某请求超时,后续请求只能阻塞。
-
Host字段,请求和响应都要包含该字段
表示当前的域名地址,目前浏览器对于同一个域名 Host,默认允许同时建立 6 个 TCP 持久连接。
-
更多的缓存字段
引入了
ETag/If-None-Match等头字段。 -
新增 6 种请求方法
2.0 版本
-
二进制分帧:将数据采用二进制编码方式,并将消息(http报文)分隔成更小的帧来传输。
-
多路复用:一个 tcp 连接中可以有多条流,也就是能同时处理多个 http 请求。
二进制帧双向传输的序列叫做流。
通过二进制分帧+多路复用,解决 http 队头阻塞。
-
头部压缩
在客户端和服务端之间建立索引表,将用到的字段存放在这张表中,传输时如果之前出现过这个值,只需要将索引传给对方即可。
-
服务端推送 Server Push
服务端不再是被动地接收请求了,它也能主动推送资源给客户端。
比如浏览器请求一个 html 文件,服务器可以在返回 html 文件基础上,主动推送其他资源。
3.0 版本
使用QUIC协议(基于 UDP),不再使用 tcp。
- 在 TCP 连接中,如果某个流的数据包传输出现问题,TCP 会等待重传、阻塞其他流的数据包【TCP队头阻塞】。
- 而 QUIC 协议中,不同流之间的数据传输是相互独立,某个数据包出现问题不会影响其他的。
7. http 协议中的并发限制
- 对于同一个协议、域名、端口的 url,浏览器一般允许同时打开 6 个 TCP 连接。
- HTTP/1.1 中一个 TCP 连接允许发起多次 HTTP 请求,但必须等待前一个请求的首个字节响应到达客户端。所以 HTTP/1.1 中浏览器对于同域名下的并发请求限制在 6 个。
- HTTP/2.0 通过多路复用解决了队头阻塞问题,客户端可以同时发送多个请求。
8. http 常见的14种状态码
1xx:继续处理
2xx:请求成功
- 200 OK:请求成功,并返回结果。
- 204 No Content:请求成功,但响应报文不含主体。
- 206 Partial Content:请求成功,只返回请求资源的一部分
3xx:重定向
- 301 Moved Permanently:永久重定向。请求的资源已经永久移动到新位置,会自动重定向。
- 302 Found:临时重定向。请求的资源暂时移动到新位置,会自动重定向。
- 304 Not Modified:资源未修改,重定向已缓存的文件。
4xx:客户端错误
- 400 Bad Request:错误请求,请求报文中存在语法错误。
- 401 Unauthorized:未授权,认证失误或没有认证。
- 403 Forbidden:服务端拒绝请求。
- 404 Not Found:未找到,服务端找不到该资源。
5xx:服务端错误
- 500 Internal Server Error:服务器内部错误。
- 501 Not Implemented:不支持客户端请求的功能。
- 502 Bad Gateway:错误网关。
- 503 Service Unavailable:服务不可用。
- 504 Gateway Timeout:网关超时,代理服务器不能及时从远程服务器获得应答。