HTTP协议详解 加强

接口由黑马提供的教学接口 API 点击查看文档

我还制作了关于HTTP知识点的 mochi 记忆卡片 HTTP


大纲链接 §

[toc]


HTTP协议简介

01. HTTP协议简介-什么是通信

通信就是信息的传递和交换

  • 通信三要素
    • 主体
    • 内容
    • 方式

02. HTTP协议简介-什么是通信协议

通信协议(Communication Protocol)时值通信的双方完成通信所必须遵守的规则和约定

  • 通俗地理解,通信双方采用约定好的格式来发送和接受消息,这种事先约定好的通信格式,就叫做通信协议

互联网中的通信协议

  • 客户端与服务器之间要实现网页内容的传输,则通信的双方必须遵守网页内容的传输协议
  • 网页内容又叫做超文本,因此网页内容的传输协议又叫做超文本传输协议(Hyper Text Transfer Protocol),简称HTTP协议

03. HTTP协议简介-什么是HTTP协议

HTTP协议即超文本传输协议,它规定了客户端与服务器之间进行网页内容传输时,所必须遵守的格式

  • 客户端要以HTTP协议要求的格式把数据提交到服务器
  • 服务器要以HTTP协议要求的格式把内容响应给客户端

04. HTTP协议简介-HTTP协议的交互模型

HTTP协议采用了 请求/响应 的交互模型

  • 客户端发起 HTTP 请求
  • 服务器返回 HTTP 响应

05. HTTP协议特性

0.5.1 无连接

  • HTTP协议限制每次连接 只处理一个请求
  • 服务器处理完客户端的请求,并发出响应之后,立即 断开连接,以此节省传输时间
  • 若想保持连接可设置字段:"Connection": "keep-alive",或使用WebSocket

0.5.2 无状态

  • HTTP协议对 事务处理 没有记忆能力
  • 后续处理如果需要先前的信息,则必须 重传,导致每次连接需要的数据量增大
  • 若想保存状态可采用:SessionCookieJWT技术

HTTP报文/消息

  • 用于HTTP协议交互的信息即为HTTP报文,分为 请求报文响应报文
  • 报文由「报文首部、空行、报文主体」构成
  • 报文首部由「起始行(请求行/状态行)、首部字段」构成
    • 请求报文首部由「请求行、首部字段」构成
      • 请求报文的 起始行 称为 请求行
      • 其包括「请求方法、请求URI、HTTP版本」
    • 响应报文首部由「状态行、首部字段」构成
      • 响应报文的 起始行 称为 状态行
      • 其包括「HTTP版本、状态码、原因短语」
    • 首部字段 分为:
      • 通用首部字段:请求报文和响应报文都会用到的首部
      • 请求首部字段
      • 响应首部字段
      • 实体首部字段:用于补充与实体相关的信息
      • 其它:RFC中未定义的首部,如为 Cookie 服务的首部字段 (CookieSet-Cookie
    • 空行用于分割 报文首部报文主体
    • 报文主体即具体数据,请求报文 对应 请求体响应报文 对应 响应体

在命令行中使用curl -v https://www.baidu.com发送请求,查看报文结构

message

HTTP请求消息

01. HTTP请求消息-什么是HTTP请求消息

  • 由于HTTP协议属于客户端浏览器和服务器之间的通信协议
  • 因此,客户端发起的请求叫做 HTTP请求
  • 客户端发送到服务器的消息(报文),叫做 HTTP请求消息(报文)

02. HTTP请求消息-HTTP请求消息的 4个组成部分

HTTP请求消息由 请求行(request linestart-line请求头部(request headers空行、和 请求体(request body 4个部分组成

request message

03. HTTP请求消息-请求行

  • 请求行由 请求方式URLHTTP协议版本 3个部分组成
  • 之间使用空格隔开
  • 通过浏览器的 Network 面板,发起 AJAX 请求时,查看请求的 标头(Headers)选项卡中的请求头 Request Headers
  • 点击查看源 (View source

start-line

浏览器打开任意网址控制台打开 Network 面板,点击 view source 查看源

Request line in Headers

  • POST /api/post HTTP/1.1即请求行
  • 并不是所有完整的 URL,是去掉 协议、域名和端口号、查询参数后的 URL

04. HTTP请求消息-请求头部

  • 请求头部用来描述 客户端基本信息,负责将客户端相关信息告知服务器
  • 请求头部 包含不同的字段
    • User-Agent 用来说明当前是什么类型的客户端(浏览器)
    • Content-Type 用描述发送到服务器的 数据格式
    • Accept 用来描述客户端能够接收 返回内容的类型
    • Accept-Language 用来描述客户端期望接收那种人类语言的文本内容
  • 请求头由多行 键/值对 组成,每行的键和值之间用英文的冒号分隔

Request Headers

常见的请求头字段

头部字段 说明
HOST 需要请求的服务器域名
Connection 客户端与服务器的连接方式:close 或者 keep-alive
Content-Length 用来描述请求体的大小
Accept 客户端可识别的响应内容类型列表
User-Agent 产生请求的浏览器类型
Content-Type 客户端告诉服务器实际发送的数据类型
Accept-Encoding 客户端可接收的内容压缩编码形式
Accept-Language 用户期望获得的自然语言的优先顺序

request headers fields

05. HTTP请求消息-空行

最后一个请求头字段的后面是一个空行,通知服务器 请求头部至此结束

  • 请求消息中的空行,用来分隔 请求头部请求体

request blank

06. HTTP请求消息-请求体

请求体中存放,是要通过 POST等方式 (非GET方式)提交给服务器的数据

  • GET 请求没有请求体,GET 请求到空行结束

request body

request body formdata


HTTP响应消息

响应消息就是 服务器响应给客户端的消息内容 ,也叫作响应报文,或者应答报文

01. HTTP响应消息-响应消息的概念以及组成部分

HTTP响应消息由 状态行(status line响应头部(response header空行、和 响应体(response body 4个部分组成

response message

02. HTTP响应消息-状态行

  • 状态行是由 HTTP协议版本状态码状态码描述 3个部分组成
  • 之间使用空格隔开

status line

status line in response headers

03. HTTP响应消息-响应头部

响应头部用来描述 服务器的基本信息

  • 响应头部由多行 键/值对 组成
  • 每行的键和值之间用英文的冒号分隔

response headers

常见的响应头字段

response header field

04. HTTP响应消息-空行

  • 在最后一个响应头部字段结束之后,会紧跟一个空行,用来通知客户端 响应头部至此结束
  • 响应消息中的空行,用来分隔 响应头部响应体

response blank

05. HTTP响应消息-响应体

  • 响应体中存放的,是服务器响应给客户端的资源内容

response_body

response body raw content


HTTP请求方法

HTTP 请求方法,属于 HTTP 协议中的一部分

请求方法的作用是:用来表明 对服务器上资源执行的操作

  • 常用的请求方法是 GETPOST

区别有:(语义、缓存、编码、传参、幂等性)

  • 语义 角度:GET 用于获取资源,POST 用于上传资源
  • 缓存 角度:GET 请求会被浏览器 主动缓存POST 不会;
  • 编码 角度:GET 必须对 URL 进行编码,POST 无限制;
  • 参数 角度:GET 参数暴露URL 中,仅接受 ASCII 字符;POST 放在 请求体 中,且参数无限制,更适合传输敏感信息;
  • 幂等性 角度:GET 是幂等的,POST 不是;

什么是幂等性?

  • 在相同条件下,一次请求 和 重复多次 请求对资源的影响是一致的,则该操作 幂等

HTTP的主要请求方法

序号 方法 描述
1 GET 查询 发送请求来获取服务器上的资源,请求体中不包含请求数据,请求数据放在请求头中
2 POST 新增 向服务器提交数据(用户注册/表单/文件上传)数据包含在请求体中提交给服务器
3 PUT 修改 向服务器提交资源,并使用提交的新数据替换掉服务器中对应的旧资源
4 DELETE 删除 请求服务器删除指定的资源
5 HEAD 请求一个与 GET请求 响应头部 相同的响应,无需响应体,不会返回所请求的实体数据,仅返回响应头;可用于确认资源是否存在或检查资源是否更新,超链接探测器很多都基于 HEAD 方法进行实现
6 OPTIONS 获取目标服务器支持的请求方法,允许客户端查看服务器的性能、AJAX跨域时的预检等
7 CONNECT 建立一个由目标资源标识的服务器的隧道
8 TRACE 沿着到目标资源的路径执行一个消息环回测试, 主要用于测试或诊断
9 PATCH 对 PUT 方法的补充,用来对已知资源进行局部更新

浏览器为什么会自动发起 OPTIONS 请求

  • 当发起 跨域请求 时,如果为 非简单请求,浏览器会自动触发 预检请求(即 OPTIONS 请求)
  • OPTIONS请求 用于确认目标资源 是否支持跨域;若为简单请求,则不触发预检,正常请求
  • 204 No Content MDN

OPTIONS盗图

也就是一旦触发预检,则发送两次请求,影响性能,可做如下优化:

  • 同域则不触发
  • 避免 OPTIONS 请求:上图为 POST 请求设置头部字段 Content-Type: application/json 后的预检请求
  • 可将其设置成 application/x-www-form-urlencoded| multipart/form-data | text/plain 之一,来规避触发预检
  • 设置请求头部字段: "Access-Control-Max-Age": 600,单位秒,一般设置为10分钟

PUT & DELETE

  • PUT用于更新替换资源,DELETE用于删除资源
  • RESTful 风格会使用 PUT & DELETE;实际开发中大家可自行评估选用 PUT & DELETE 还是 POST

CONNECT

  • 创建隧道,用于代理服务器

HTTP响应状态码

01. HTTP响应状态码-什么是HTTP响应状态码

HTTP 响应状态码(HTTP Status Code),也属于 HTTP 协议的一部分,用来标识响应的状态

  • 响应状态码会随着响应消息一起被发送至客户端浏览器
  • 通过浏览器根据服务器返回的响应状态码,就能知道这次 HTTP 请求的结果是成功还是失败了

02. HTTP响应状态码-HTTP响应状态码的组成及分类

  • HTTP 状态码由三个十进制数字组成
    • 第一个十进制数字定义了状态码的类型
    • 后两个数字用来对状态码进行细分
  • HTTP 状态码共分为 5 种类型
分类 分类描
1** 信息,服务器收到请求,需要请求者继续执行操作(实际开发中很少遇到 1** 类型的状态码)
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

03. HTTP响应状态码-2xx成功相关的响应状态码

2** 范围的状态码,表示服务器已成功接收到请求并进行处理

  • 常见的 2** 类型的状态码如下:
状态码 状态码英文名称 中文描述
200 OK 请求成功。一般用于 GET 与 POST 请求
201 Created 已创建。成功请求并创建了新的资源,通常用于 POST 或 PUT 请求
204 No Content 请求成功,但无内容返回
206 Partial Content 客户端进行范围请求,响应报文中返回由 Content-Range 指定范围的实体内容

04. HTTP响应状态码-3xx重定向相关的响应状态码

3** 范围的状态码,表示服务器要求客户端重定向,需要客户端进一步的操作以完成资源的请求

  • 常见的 3** 类型的状态码如下:
状态码 状态码英文名称 中文描述
301 Moved Permanently 永久移动。请求的资源已被永久地移动到新的 URI,返回信息会包括新的 URI,浏览器会自动重定向到新的 URI。并标记今后任何新的请求都应使用新的 URI 代替;响应的 Location 头字段会提供资源现在的 URL。直接使用 GET 方法发起新情求。
302 Found 临时移动。与 301 类似。但资源只是临时被移动。客户端只应该将 Location 返回的 URL当做临时资源来使用。直接使用 GET 方法发起新情求。客户端今后应继续使用原有 URI 请求资源
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源(响应消息中不包含响应体)。客户端通常会缓存访问过的资源,即可直接使用客户端未过期的缓存(资源未修改,表示本地缓存仍然可用)

补充 HTTP 重定向相关

  • HTTP 中,如果服务器返回了一个重定向响应进行重定向并且是以3开头的状态码,里面有一个 Location 头字段表示要重定向的位置。浏览器收到响应后会直接加载 Location 里指定的 URL
  • 状态码301308都属于永久重定向,永久重定向意味着原始 URL 不再可用,替换成了一个新的内容。所以搜索引擎以及其他爬虫识别这两个状态码时,会更新旧 URL 的资源。
  • 302/303/307 都属于临时重定向

05. HTTP响应状态码-4xx客户端错误相关的响应状态码

4** 范围的状态码,表示客户端的请求有非法(不合语法)内容,从而导致请求失败

  • 常见的 4** 类型 的状态码如下:
状态码 状态码英文名称 中文描述
400 Bad Request 1 语义有误。当前请求无法被服务器理解。除非进行修改,否则客户端不应重复提交这个请求;2 请求参数有误
401 Unauthorized 未经授权认证。当前请求需要用行用户验证
403 Forbidden 服务器已经理解请求,但是拒绝执行
404 Not Found 服务器无法根据客户端的请求找到资源(通常是网页)
408 Request Timeout 请求超时。服务器等待客户端发送的请求时间过长,超时

06. HTTP响应状态码-5xx服务端错误相关的响应状态码

5** 范围的状态码,表示服务器未能正常处理客户端的请求,而出现意外错误

  • 常见的 5** 类型的状态码如下:
状态码 状态码英文名称 中文描述
500 Internal Sever Error 服务器内部错误,无法完成请求
501 Not Implemented 未实现请求方法 。服务器不支持该请求方法,无法完成请求。 只有 GET 和 HEAD 这两种请求是要求每个服务器必须支持的,其它请求方法在不支持的服务器上会返回 501
503 Service Unavailable 由于超载或系统维护,服务器暂时地无法处理客户端的请求

可以一同记忆的状态码

状态码 状态码英文名称 中文描述
206 Partial Content 部分内容。成功状态响应代码表示请求已成功,并且主体包含所请求的 数据区间,该数据区间是在请求的 Content-Range 首部指定的
416 Range Not Satisfiable 服务器无法处理所请求的 数据区间。所请求的数据区间不在文件范围之内,即 Content-Range 首部的值,虽然从语法上来说是没问题的,但是从语义上来说却没有意义

其他HTTP相关知识点的有:HTTP缓存、HTTP状态管理、HTTP内容协商、HTTP持久连接机制、代理-网关-隧道、HTTP范围请求、HTTPS相关

HTTP缓存

强缓存 V.S 协商缓存

  • 两者的区别在于:
    • 是否需要向服务器 验证本地缓存 是否有效
    • 强缓存 直接使用 本地缓存
    • 协商缓存则需 与服务器进行协商 后,确定是否使用本地缓存

强缓存

  • 响应头部字段中设置 Cache-Control: max-age=xxx,public
  • 表示在xxx秒内再次访问该资源,均使用本地缓存
  • public 表示允许客户端及代理服务器(CDN)缓存

General

  • 命中缓存 -Status Code: 200 (from memory cache) -Status Code: 200 (from disk cache)
  • 这里浏览器会自动分配存储到内存(memory cache)中还是磁盘(disk cache)中

存在的问题

  • 感知不到资源更新,缓存不过期则不会重新获取

解决

  • 缓存的意义在于减少请求,更多的使用本地资源,给用户更好的体验同时减轻服务器压力
  • 所以最佳实践应尽可能命中强缓存,同时在更新资源时让客户端的缓存失效
  • 在打包静态资源文件时,根据内容进行 hash 计算,以此来生成文件名
  • 此时请求资源URL改变,浏览器重新加载资源

协商缓存

General

  • 命中缓存 -Status Code: 304 (Not Modified)
  • 未命中缓存 -Status Code: 200 (OK)

Response Headers中的Last-Modified, 与Request Headers中的If-Modified-Since

  • 文件时间戳对比
  • 首次请求资源时,服务器返回的首部字段中会携带 Last-Modified
    • 值为 GMT 时间戳
  • 当再次请求资源时,浏览器会自动带上 If-Modified-Since,该值与 Last-Modified 做对比
    • 若相同,则返回304,命中缓存
    • 若不同则返回200,发送最新资源

存在的问题

  • Last-Modified 记录的是精确到秒的时间格式,若在 1s 内资源发生变化,则 Last-Modified 感知不到,无法返回新资源
  • 协商缓存最大的问题就是每次都要向服务器验证一下资源的有效性

EtagIf-None-Match 文件Hash值对比

  • 首次请求资源时,服务器返回的首部字段中会携带 Etag
  • 当再次请求资源时,浏览器会自动带上 If-None-Match,该值与 Etag 做对比
  • 实体标识EtagIf-None-Match配对
    • 若相同,则返回304,命中缓存
    • 若不同则返回200,则资源已更改,发送最新资源

EtagIf-None-Match优先级高于Last-ModifiedIf-Modified-Since

  • Last-Modified 相比,Etag 是根据文件内容生成的唯一标识
  • 当文件变化,则 Etag 变化
  • 两者同时存在时,Etag 优先级高于 Last-Modified

总结

  • 能够说出什么是HTTP协议
  • 能够知道HTTP请求消息的组成部分
  • 能够知道HTTP相应消息的组成部分
  • 能够说出常见的请求方法
  • 能够说出常见的响应状态码


参考文章

相关文章


  • 作者: Joel
  • 文章链接:
  • 版权声明
  • 非自由转载-非商用-非衍生-保持署名