http知识点梳理

http 是应用层协议,且是无状态的。它时基于 TCP/IP 的通信协议,用于在网络中传递数据,默认端口号 TCP 80.HTTP 规范指定如何构造客户端的请求数据并将起发送到服务器,以及服务器如何响应这些数据。

基本特性

有 3 个基本特性使得 HTTP 成为一个简单且强大的协议:

  • HTPP 是无连接的,客户端和服务器仅在当前请求和响应期间是相互知道对方,进一步的请求会建立新的连接,就像客户端和服务器彼此是新的一样
  • HTTP 是独立于媒体,与媒体无关的,这意味,只要客户端和服务器都知道如何处理数据内容,任何类型的数据都可以通过 HTTP 发送。因此,客户端和服务器都需要使用适当的MIME-type来指定内容类型
  • HTTP 是无状态的,如上所述,HTTP 是无连接的,只在当前请求期间,客户端与服务器才能相互感知,之后,就会忘记对方。因此,客户端和服务器都不能在跨 web 页面的不同请求之间保留信息。

HTTP/1.0 为每个请求/响应交换 使用一个新连接,而 HTTP/1.1 一个连接可以用于一个或多个 请求/响应交换

基础架构

HTTP Basic Architecture

HTTP 协议是基于客户端/服务器架构的请求/响应协议。其中 web 浏览器,搜索引擎等充当 HTTP 的客户端,web 服务器充当服务器

Client 客户端

HTTP 客户端以 请求方法+URL+协议版本的形式向服务器发送消息,然后通过 TCP/IP 连接发送一个类似 mime(MIME-like)的消息,其中包含请求修饰符客户机信息,可能的主体内容

Server 服务器

HTTP 服务器使用一个状态行(消息协议版本 + 成功或错误代码)进行响应,然后是一个类似 mime 消息,其中包含服务器信息实体元信息,可能的实体-主体信息

HTTP-参数

版本

HTTP/1.0, HTTP/1.1

同一资源标识符(URI)

不区分大小写,一般语法

1
URI = "http:" "//" host [":" port] [abs_path ["?" query]]
  • 如果port为空,则默认 HTTP 端口号 80;
  • 如果abs_path为空,则相对于/
  • 除保留字符和有特殊含义的字符之外的字符会被进行编码,等效于%+十六进制编码

日期/时间格式

所有 HTTP 日期/时间戳,必须用格林威治时间表示 last-modified: Sat, 11 Apr 2020 02:05:18 GMT

字符集

指定客户端喜欢字符集,多个字符集用逗号分隔;如果未指定,默认为 US-ASCII

内容编码

在通过网络传递内容之前,使用编码算法对内容进行编码,主要用于在不丢失标识的情况下对文档进行压缩或其他转化。内容编码的值是大小写不敏感的,在HTTP/1.1中,Accept-EncodingContent-Encoding头字段中使用内容编码值

1
2
3
4
5
6
7
Accept-encoding: gzip

Accept-encoding: compress

Accept-encoding: deflate

Content-encoding: gzip

媒体类型

Content-TypeAccept头字段中使用互联网媒体类型,以便提供开放的,可扩展的数据类型和类型协商。所有的媒体类型的值都在互联网号码分配机构(IANA)注册,可查看媒体类型最新列表
MIME 类型对大小写不敏感,其通用结构:type/subtype

独立类型

独立类型表明了对文件的分类

类型 说明 示例
text 普通文本,理论上是人可读的 text/plain,text/html,text/css,text/javascript
image 图像,包括 gif 动图 image/gif,image/png,image/jpeg,image/x-icon
audio 音频文件 audio/midi,audio/mpeg,audio/webm,audio/ogg
video 视频文件 video/webm,video/ogg
application 某种二级制数据 application/octet-stream,application/xml,application/pdf

复合(Multipart)类型

1
2
3
multipart/form-data

multipart/byteranges

Multipart 类型表示细分领域的文件类型,是复合文件的一种表现方式。
multipart/form-data 用于HTML FormsPOST方法;multipart/byteranges使用状态码 206 Partial Content来发送整个文件的子集。
HTTP 对不能处理的复合文件使用特殊的方式:将信息 直接传给浏览器(这是可能会建立一个“另存为”窗口,但是不知道如何去显示文件)

语言标签

HTTP 在Accept-LanguageContent-Language字段使用语言标签,它是由一个主语言和一系列的子语(可能为空)言组成。不允许有空格,且大小写不敏感。

1
2
3
Accept-language: en,zh-CN;q=0.9,zh;q=0.8,la;q=0.7

// q 表示对该语言的喜好程度,0-1之间

HTTP-header 字段

HTTP 消息头允许客户端和服务器通过请求,响应来传递附加信息。一个请求头由名称(不区分大小写)后跟一个冒号:,冒号后再跟具体的值(不带换行符)组成。
根据不同上下文,消息头可分为:

  • General headers: 同时适用于请求和响应消息,但是不能应用于内容本身。常见的有DateCache-ControlConnection
  • Request headers: 包含更多有关要获取的资源或客户端本身信息的消息头
  • Response headers: 包含有关响应的补充信息
  • Entity headers: 包含有关实体主体的更多信息

通用的头字段

  • Cache-Control: 被用在请求和响应中,通过指令来实现缓存机制。指令不区分大小写,具有可选参数,多个指令以逗号分隔
    • 缓存请求指令
      • no-cache: 在没有与原始服务器成功验证的情况下,缓存不得使用。即在发送缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)
      • no-store: 缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存
      • max-age = seconds: 设置缓存存储的最大周期,超过该时间缓存被认为过期
      • max-stale [=seconds]: 表示客户端愿意接受超过到期时间的响应。如果给定了时间,它的过期时间不得超过该时间。
      • min-fresh= seconds: 表示客户端愿意接受还剩余多少秒过期的缓存
      • only-if-cached: 表示客户端直接受已缓存的响应,并且不要向原始服务器检查是否有更新的拷贝。
    • 缓存响应指令
      • public: 表明响应可以被任何对象(包括 客户端,代理服务器,等待)缓存
      • private: 响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存),私有缓存可以缓存响应内容,比如,对应用户的本地浏览器
      • must-revalidate: 一旦资源过期,在成功向原始服务器验证之前,缓存不能用该资源响应后续请求
      • proxy-revalidate: 代理重新验证指令,与must-revalidate作用相同,但它仅适用于共享缓存,被私有缓存忽略
  • Connection: 决定当前事务完成后,是否关闭网络连接;值为”keep-alive”,网络连接是持久的,不会关闭,使得对同一服务器的请求可以继续在该连接上完成。”close”,关闭该网络连接
  • Date: 报文创建的日期和时间。在 HTTP 协议中,时间都是用格林威治标准时间来表示,而非本地时间。<day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT,Date: Tue, 14 Apr 2020 23:40:03 GMT
  • Via: 网关和代理必须使用Via来指示中间协议和接收者。可用来追踪消息转发情况,防止循环请求

请求消息的头字段

  • Accept: 请求头用来告知服务器,客户端可处理的内容类型,用 MIME 类型表示。借助内容协商机制,服务器可以从诸多备选项中选择一项进行应用,并使用Content-Type通知客户端它的选择
  • Accept-Charset: 用来告知服务器,客户端可以处理的字符集类型。服务器使用Content-Type应答。Content-Type: text/hml; charset=utf-8
  • Accept-Encoding: 用来告知服务器,客户端能够理解的内容编码方式,通常是某种压缩算法。服务器使用Content-Encoding应答 值indentity,未经过压缩和修改
  • Accept-Language: 客户端可理解的自然语言
  • Authorization: 请求消息头含有服务器 用于验证用户代理身份的凭证,通常会在服务器返回401 Unauthorzied状态码之后,在后续请求中发送此消息头。Authorization: <type> <credentials>, Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l,“基本验证(Basic)”,用冒号将用户名和密码进行拼接(username:password),再用 base64 方式编码
  • Cookie: 其中含有先前由服务器通过Set-Cookie首部存储到客户端的HTTP cookies,其值是一系列的名称/值对,之间用分号和空格隔开。Cookie: PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;
  • Host: 指明了服务器的域名,以及服务器监听的 TCP 端口号,默认 80.HTTP/1.1请求缺少 Host 头字段,返回400 Bad Request状态码
  • If-Match: 表示这是一个条件请求
    • 在 GET,HEAD 请求,服务器仅在请求的资源满足此首部的ETag值时才会返回资源。
    • 对 PUT 请求,只有在满足条件的情况下才可以将资源上传
  • If-Modified-Since: 是一个条件式的请求首部,如果在该字段中指定的时间以来,请求的资源未被修改,则返回一个不带消息主体的 304 Not Modified 响应。如果资源修改过,则返回 200 Ok.在Last-Modified响应首部中会带有上次修改的时间。如果没有ETag匹配,则服务器不能执行该请求方法,返回412 Precondition Failed
  • If-None-Match: 是一个条件式请求。当且仅当服务器上没有任何资源的ETag的值与此首部中列出的相匹配时,才返回200 Ok.2 个常见应用场景
    • 采用 GET,HEAD 方法,来更新拥有特定的 ETag 属性值的缓存
    • 采用其他方法,尤其是 PUT,将If-None-Match的值设置为 *,(可以代表任意资源),来检查拥有相同 ID 的资源是否存在,如果存在,则验证失败,服务器返回412 Precondition Failed(前置条件失败)
    • User-Agent: 包含有关发送请求的用户代理的信息,软件类型、操作系统、开发商、版本号等。要避免进行用户代理检测,因为为不同浏览器提供不同的网页或服务通常是一个坏主意
      • 功能检测,弄清楚浏览器中某种特定功能是否可用,如果不可用,找应变策略
      • 渐进增强,自底向上的方法,从一个简单的层次开始,在一系列连续的层次中通过使用更多的功能来逐步提升站点的能力
      • 优雅降级,自顶向下的方式,先使用所有想要的功能,然后改进使其能在更老旧的浏览器上工作,与渐进增强的方式相比,这种方法更困难,效率更低

响应消息的头字段

  • ETag: 资源是特定版本的标识符。如果给定 URL 中的资源更改,则一定要生成新的 ETag 值。常见的应用场景
    • 避免“空中碰撞”,借助ETagIf-Match头部,可以检测到“空中碰撞”的编辑冲突,POST 请求将包含有 ETag 值的If-Match头来检查是否为最新版本,如果不匹配,则意味已经被编辑,返回412前置条件失败错误
    • 缓存未更改的资源,在请求时发送值为 ETag 的If-None-Match字段,服务器与其当前版本资源的 ETag 进行比较,如果两个值匹配,即资源未更改,返回304
  • Location: 指定了需要将页面重定向到的地址,一般在状态码为3XX的响应中才会有意义
  • Retry-After: 表示客户端需要等待多长时间后才能继续发送请求。经常同503 Service Unavailable, 当前服务不存在响应一起使用,表示服务器下线的预期时长,可用于对于计划内宕机时间的处理
  • Server: 处理请求的源头服务器所用的软件相关信息
  • Set-Cookie: 被用来由服务器端向客户端发送 cookie,即设置此网址的 cookie Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

实体消息(Entity Headers)的头字段

  • Allow: 资源所支持的 HTTP 方法的合集。若服务器返回状态码405 Method Not Allowed,则该首部字段需要同时返回给客户端
  • Content-Ecoding: 表示消息主体进行了何种方式的内容编码(压缩)。如果源服务器不接受请求信息中的内容编码,服务器返回415 Unsupported Media Type
  • Content-length: 用来指明发送给接收方的消息主体的大小
  • Content-Type: 消息主体的媒体类型
  • Expires: 响应过期是日期/时间。 0,代表过去时间,即资源已经过期。如果在Cache-Control响应头设置了max-ages-max-age指令,则Expires会被忽略
  • Last-Modified: 源服务器中资源最后修改的日期/时间

HTTP-消息

HTTP 是基于客户机-服务器体系结构模型,无状态请求/响应协议,通过可靠的 TCP/IP 来交换消息。
HTTP 利用 URI 来标识给定的资源并建立连接,一旦建立了连接,HTTP 消息将以 MIME 类型传递。这些消息包含从客户机到服务器的请求和从服务器到客户机的响应。
HTTP 请求和响应使用 RFC 822 的通用消息格式来传输所需的数据,此通用消息格式由四个部分组成:起始行,头部空行,消息正文

http message

HTTP-请求

http-请求方法

HTTP 定义了一组请求方法,以表明要对给定资源执行的操作。

  • GET:使用给定 URL 从服务器获取数据,且不会对数据产生其他影响

  • HEAD: 请求资源的头部信息, 且与 GET 方法请求时返回的一致,不包含响应正文。使用场景,在要下载一个大文件前先获取文件大小后再决定是否要下载,以节约带宽资源

  • POST: 发送数据给服务器,请求主体的类型由Content-Type首部指定
    PUT 方法是幂等(idempotent,指同样的请求被执行一次或连续执行多次的效果是一样的)的,即连续调用一次或多次的效果相同(无副作用),但 POST 不是,连续调用可能会带来额外的影响,比如多次提交订单
    POST 请求通常通过 HTML 表单发送,并返回服务器的修改结果,在这种情况下,content-type是通过在<form>元素中设置正确的enctype属性,或在<input>,<button>元素中设置formenctype属性来选择的,如application/x-www-form-urlencoded multipart/form-data``text/plain

  • PUT: 使用请求中的内容创建或替换目标资源

    • 如果目标资源不存在,并且 PUT 方法成功创建了一份,则服务器必须返回201 Created来通知客户端资源已创建
    • 如果目标资源已经存在,且成功进行了更新,则服务器必须返回200 OK204 No Content来表示请求成功完成
  • PATCH:用于对资源进行部分修改,不同与 PUT 对资源进行整体覆盖。PATCH 方法是非幂等的,如何理解?
    PATCH 请求中的实体保存的是修改资源的指令,该指令指导服务器来对资源做出修改,例如,对于服务器的 A 对象有个属性 b 为 1,如果要修改为 3,PUT 请求直接将改过的 b 属性的整个新对象发送给服务器查找并替换;而 PATCH 请求是在实体中包含指令:将 A 对象中的 b 属性的值+2,所有如果该请求被执行多次,b 属性就不是 3 了。

  • DELETE: 删除指定的资源,是幂等的。如果成功执行,会有以下几种状态码:

    • 202 Accepted, 表示请求的操作可能会成功执行,但是尚未开始执行
    • 204 No Content, 操作已执行,但无进一步的相关信息
    • 200 OK,操作已执行,并且响应中提供了相关状态的描述信息
  • OPTIONS: 用于获取目的资源所支持的通信选项。客户端可对特性 URL 使用 OPTIONS 方法,也可对整站(RUL 设置为*)使用该方法

    • 检测服务器所支持的请求方法,响应报文会包含Allow首部字段,该字段的值表明了服务器支持的所有 HTTP 方法

      1
      $ curl -X OPTIONS http://example.org -i
HTTP/1.1 200 OK
Allow: OPTIONS, GET, HEAD, POST
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Tue, 14 Apr 2020 03:21:01 GMT
Expires: Tue, 21 Apr 2020 03:21:01 GMT
Server: EOS (vny/0454)
Content-Length: 0
```
  • 在中的预检请求,在CORS中,使用 OPTIONS 方法发起一个预检请求,以检查请求是否被服务器接收。

HTTP-响应

  • 状态行: 协议版本 状态码 状态文本HTTP/1.1 404 Not Found
  • Headers: 遵循和任何其它 header 相同的结构
  • Body: 不是所需响应都有 body

HTTP-状态码

HTTP 状态码可分为 5 种类型

分类 描述
1XX 信息性状态码,服务器收到请求,需要请求者继续执行操作
2XX 成功状态码,操作被成功接收并处理
3XX 重定向,需要进一步的操作以完成请求
4XX 客户端错误,请求包含语法错误
5XX 服务器错误,服务器在处理请求的过程中发生了错误

常用状态码

  • 200 OK: 请求已经成功,默认情况下状态码为 200 的响应可以被缓存。

  • 201 Created: 请求已经被成功处理,并且创建了新的资源,常作为POST请求的返回值

  • 204 No Content: 请求成功,但没有资源返回给客户端。常用于在PUT请求进行资源更新时,如果创建了资源,则返回201 Created

  • 206 Partial Content: 对资源某一部分的请求,响应报文中包含由 Content-Range 指定范围的实体内容

  • 301 Moved Permanently: 永久重定向,请求的资源已经被移动到由Location头部指定的 URL 上,因为有些用户代理在进行重定向时会改变请求 method 和 body,用308 Permanent Redirect,它不会。

  • 302 Found,请求的资源被暂时的移动到由Location头部指定的 URL 上。部分用户代理在重定向时无法保证请求 method 和 body 不变,推荐使用307 Temporary Redirect.

  • 303 See Other: 通常作为PUTPOST操作的返回结果,它表示重定向的链接指向的不是新上传的资源,而是另一个页面,比如信息确认页面或上传进度页面,且方法总是使用GET

  • 304 Not Modified: 未改变,说明无需再次传输请求的内容,可以使用缓存的内容

  • 400 Bad Request: 表示服务器无法理解的请求,请求报文中可能存在语法错误

  • 401 Unauthorized: 缺少目标资源要求的身份验证凭证,这个状态码会和www-Authenticate头部一起返回,其中包含有如何进行验证的消息

  • 403 Forbidden: 指定是服务器有能力处理请求,但是拒绝授权(没权限,未授权 IP 等)

  • 404 Not Found: 服务器无法找到请求的资源,路径错误

  • 405 Method Not Allowed: 表明服务器禁止使用当前的 HTTP 方法的请求

  • 500 Internal Server Error: 服务器遇到意外的情况,并阻止其执行请求。通用的“万能”的错误响应

  • 502 Bad Gateway: 表示最为网关或代理角色的服务器,从上游服务器中接收到的响应式无效的。

  • 503 Service Unavailable: 表示服务器尚未处于可接受请求的状态。原因可能是停机维护或者已超载。在必要可行的情况下,应该在Retry-After头部包含服务恢复的预期时间