HTTP 协议

183 阅读8分钟

1. http 协议的报文格式

http 是应用层协议,是浏览器和服务器之间的请求、响应的格式和规则

  1. 请求报文格式
请求行(请求方法 + url + http版本号)
请求头
空行
请求体
  1. 响应报文格式
状态行(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
  1. 参数的传递方式

    • get 请求的参数通过 url 传递
    • post 请求的参数放在请求体
  2. 参数大小限制

    • get 请求的参数有大小限制(2KB,因为 url 本身的限制)
    • post 没有限制
  3. 安全性:因为 get 请求参数放在 url 中,所以不如 post。

  4. 主动缓存:get 请求浏览器会主动缓存,post 默认不会。

  5. 幂等:get 请求是幂等的,post 不是。

5. http 常用头部字段

建议先了解浏览器缓存。

  1. 通用头:请求头和响应头的通用头部。

    • cache-control(http1.1):用于控制缓存。
      • public:响应的所有内容都可以被客户端、代理服务器等任何对象缓存。
      • private:默认值,只能被客户端缓存,不能被代理服务器缓存。
      • no-cache:会缓存,但每次发请求时都需要用ETag字段向服务器验证是否要使用缓存,如果缓存没变化则返回 304,继续使用缓存。
      • no-store:禁止缓存
      • max-age=xxx:缓存内容将在 xxx 秒后失效。
    • Connection
      • keep-alive:默认持久连接。(使用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,不需要用新的)
      • close:请求响应完成之后立即关闭连接。
  2. 请求头

    • 【If-Modified-Since】:将Last-Modified的值发送给服务器,询问文件是否已经过期。过期则返回新资源,否则返回 304。
    • 【If-None-Match】:将ETag的值发送给服务器,询问文件是否过期。过期则返回新资源,否则 304。
    • Host:服务器的域名。
    • Referer:发起请求的页面的原始 url。
    • Cookie:发送给服务端的 cookie 信息。
    • Accept:告诉服务端,客户端接收什么类型的响应。
    • Accept-Encoding:能正确接收的编码格式列表。
    • User-Agent:告诉服务端,客户端使用的操作系统、浏览器版本和名称。
  3. 响应头

    • Location:需要将页面重定向的地址,一般状态码为 3xx 才有效。
    • 【ETag】:当前资源在服务器的唯一标识符。
    • Set-Cookie
  4. 实体头:请求体和响应体使用的首部。

    • 【Allow】:资源可支持的 http 请求方法。
    • 【Last-Modified】:资源的最后修改时间,精度不如 ETag。因为只打开文件不修改,值也会变。
    • 【Expires】:响应过期时间。(http 1.0)
    • Content-Type:客户端告诉服务器实际发送的数据类型。

6. http 不同版本的区别

1.0 版本

浏览器每次请求都需要与服务器建立一个 tcp 连接,完成请求后立即断开。

1.1 版本

  1. 默认长连接:Connection: keep-alive

    数据传输完成后保持 tcp 连接不断开,因此可以在一个 tcp 连接中发送多个 http 请求。

    客户端不用等待上一次结果返回就可以发送下一次请求,但服务端必须按照接收到请求的顺序依次返回响应结果。

    http 队头阻塞:若干请求排序串行处理,一旦某请求超时,后续请求只能阻塞。

  2. Host字段,请求和响应都要包含该字段

    表示当前的域名地址,目前浏览器对于同一个域名 Host,默认允许同时建立 6 个 TCP 持久连接。

  3. 更多的缓存字段

    引入了ETag/If-None-Match等头字段。

  4. 新增 6 种请求方法

2.0 版本

  1. 二进制分帧:将数据采用二进制编码方式,并将消息(http报文)分隔成更小的帧来传输。

  2. 多路复用:一个 tcp 连接中可以有多条流,也就是能同时处理多个 http 请求。

    二进制帧双向传输的序列叫做流。

    通过二进制分帧+多路复用,解决 http 队头阻塞。

  3. 头部压缩

    在客户端和服务端之间建立索引表,将用到的字段存放在这张表中,传输时如果之前出现过这个值,只需要将索引传给对方即可。

  4. 服务端推送 Server Push

    服务端不再是被动地接收请求了,它也能主动推送资源给客户端。

    比如浏览器请求一个 html 文件,服务器可以在返回 html 文件基础上,主动推送其他资源。

3.0 版本

使用QUIC协议(基于 UDP),不再使用 tcp。

  • 在 TCP 连接中,如果某个流的数据包传输出现问题,TCP 会等待重传、阻塞其他流的数据包【TCP队头阻塞】。
  • 而 QUIC 协议中,不同流之间的数据传输是相互独立,某个数据包出现问题不会影响其他的。

7. http 协议中的并发限制

  1. 对于同一个协议、域名、端口的 url,浏览器一般允许同时打开 6 个 TCP 连接。
  2. HTTP/1.1 中一个 TCP 连接允许发起多次 HTTP 请求,但必须等待前一个请求的首个字节响应到达客户端。所以 HTTP/1.1 中浏览器对于同域名下的并发请求限制在 6 个。
  3. 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:网关超时,代理服务器不能及时从远程服务器获得应答。