HTTP 的原理和工作机制(一)

2019-01-20  本文已影响217人  valentizx

HTTP 是什么?

Hyper Text Transfer Protocol 超文本传输协议,是一种 Client 和 Server 之间请求和应答的标准,目的是更高效的进行网络传输。

HTTP 工作方式

用户最直观的感受就是浏览器地址栏键入地址->回车->看到浏览器呈现的网页,这个过程简单的流程就是:
浏览器发送请求到服务器,服务器响应请求,浏览器通过渲染引擎渲染网页结果,渲染引擎也就是浏览器的内核。

image.png

示例地址:https://twitter.com/shaddeen_/followers

shaddeen,是小众音乐播放器 Loud 和 SmartPlayer 的作者。

所以在这个从按下回车到直观看到界面的过程就简单的概括为 3 步:

  1. 请求
  2. 响应
  3. 渲染

在请求的过程中,浏览器地址栏的 URL 转化成 HTTP 报文进行发送,一个 URL 大致分为三个部分:
https/http: 协议类型twitter.com 服务器地址shaddeen_/followers 路径(path)

请求发送的形式就变成:

GET /shaddeen_/followers HTTP/1.1
Host: twitter.com

在这个过程中,两个极其重要的角色也就出现了:Request 和 Response。

Request 报文格式

简易的 Request 报文格式如下:

GET /shaddeen_/followers HTTP/1.1
Host: twitter.com

GET /shaddeen_/followers HTTP/1.1为一个请求行,分三个部分:

Host: twitter.com 为请求 Headers,可为多行(包括更多的内容如 Content-Type: text/plain Content-Length: 240)
另,请求可以加入 Body,可以加入实际的内容,该内容是服务器需要处理的。Body 和请求行中的 path 都是和服务器对接并需要服务器处理的,但是各自角色的定位并不一样。

Response 报文格式

Response 的报文同样也有 Headers 和 Body,相比 Request 无请求行,多了一个状态行,例:

状态行️
HTTP/1.1 200 OK
Headers️
content-type: application/json; charset=utf-8
cache-control: public, max-age=60, s-maxage=60
vary: Accept, Accept-Encoding
etag: W/"02fjsdarwr080823f"
content-encoding: gzip
Body️
[
    name: "shaddeen_",
    id: "2342242",
    follow_list: [
        ...
    ]
    ...
]

HTTP/1.1 200 OK 亦分为三个部分:

这三部分的组合可以简单地描述一次请求。

Request Method

Status Code

作用:对结果作出类型化描述(如「成功」、「未找到」)。

通常规范化的状态码有 5 类,分类是为了方便调试:

Header

作用:Header 描述了 HTTP 消息的元信息 (Meta Data),通俗地说就是描述数据的数据,如:该消息有多长?是什么格式?数据有没有压缩?返回的数据是什么字符集等等。

Host

在前面的例子中,有一个 Host 的字段,它表示服务器主机地址,但是它不是用来寻址的,寻址的过程在发送请求之前就已经做好了

在发送请求前,浏览器会带着域名「询问」 DNS(Domain Name System 域名系统) 目标 IP 地址,然后 DNS 返回一个或多个 IP 地址,然后通过 IP 地址去寻址,然后发送报文给目标服务器。

那么为什么在请求 Header 中为什么还要带上 Host ?

是因为一个服务器主机下可能有多个虚拟主机或多个子服务器(多个网站)存在,也就是同样一个 IP 地址下面会有多个服务器存在,由于它们对外的 IP 都是一样的,浏览器根据这个 IP 去请求服务器,服务器会无法识别该次请求访问具体哪个主机,最终得不到正确的响应,所以需要发送 Host 附加到 Header 到服务器。

服务器地址一般的形式是:域名 + TCP 端口。

Content-Type/Content-Length

描述 Body 的类型和长度。

为什么会有 Content-Type 的存在?

是因为请求报文中,可能会携带二进制非文本数据,二进制数据本身是不受限制的,它表示着各种各样的字节,那么如何表示内容字节结束?此时 Content-Type 的作用就是表示规定一个长度,长度范围内读取数据,长度过后的数据,直接扔弃。

text/html: html 文本,用于浏览器页面响应。
application/x-www-form-urlencoded: 普通表单,encode URL 格式,只作用于文本。

表单,可以简单的理解为:一个要提交的表,是浏览器和服务器沟通的一个格式。通过表单,服务器会解析本次请求的 Body 内容,找对应参数。

multipart/form-data: 多部分形式,一般用于包含二进制内容的多项内容。后面会跟 boundary=----WebKitFormBoundaryxxxxxx,它的作用是用来分界 Body 和 Header 以及 Body 的各个属性。如修改人物信息的时候,通常会附带普通的「名字信息」和「头像图片」,那么请求格式如下:

POST /users HTTP/1.1
Host: twitter.com
Content-Type: multipart/form-data boundary=----WebKitFormBoundary247HFSSj7fgwj01
Content-Length:2300
------WebKitFormBoundary247HFSSj7fgwj01 // 分界 
Content-Disposition:form-data; name="user_name"// user_name 属性
valentizx
------WebKitFormBoundary247HFSSj7fgwj01 // 分界 
Content-Dispostion: form-data; name="avatar";filename="valentizx.jpg" // avatar 属性
Content-Type: image/jpeg
SFH72jfoa6GSKHGS....

------WebKitFormBoundary247HFSSj7fgwj0-- // 分界 

分界前面有 6 个 「-」,前两个「-」表示一个新的属性的开始,最后一个分界后面有两个「-」表示结束。

application/json: json 形式,多用于 Web Api 的响应或 PUT/POST 请求
image/jpeg、application/zip ...: 但文件,用于 Web Api 响应或 POST/PUT 请求。

Chunked Transfer Encoding 分块传输

当一次请求的响应数据内容较大时,为不影响用户体验,服务器通常会返回一个 chunk 单位的数据给客户端,但是服务器不会告诉 Header 每一个 chunk 具体多长,也就是 Body 长度无法确定,此时 Content-Type 无法使用。于是,新的 Body 格式出现:

<length1>
<data1>
<length2>
<data2>
0
 // ️此处有换行位️

明确每一小段(chunk)的长度放到 Header 中,先传输 data1,当 data2 准备就绪的时候传输 data2,直到传输 0 + 换行 表示内容结束。

Location

重定向的目标 URL,一次请求返回 301 的时候,浏览器会进行重定向到 Location 字段后的地址再进行一次请求。

User-Agent

用户代理,就是指客户端(Client),网页会根据不同的设备进行适配,标识凭借就是 User-Agent。

Range/Accept-Range

指定 Body 的内容范围,当目标服务器支持分段取内容的时候,该字段发挥作用,其最主要的两个应用点就是:断点续传分段下载

Cookie/Set-Cookie

发送 Cookie,设置 Cookie

Authorization

授权信息

部分其他 Header

Accept: 客户端能接受的数据类型。如 text/html
Accept-Charset: 客户端度接受的字符集。如 utf-8
Accept-Encoding: 客户端接受的压缩编码类型。如 gzip
Content-Encoding: 压缩类型。如 gzip

Cache

Cache 和 Buffer

Cache-Control

no-cacheno-storemax-age:

Last-Modified

If-Modified-Since: 缓存界面最后的修改时间,请求过程中,服务器会对比缓存的最后修改时间和真实文件的最后修改时间,如果一致,说明文件没有改动过,返回 304,否则返回 200 和新的内容。

Etag

If-None-Match: 相当于 Hash,或者说相当于一个指纹,Client 端也可凭借该字段与服务器「沟通」,对比这个标签,如果不是最新的,则请求最新的,返回 200 显示新内容,如果一致,则 返回 304。

Cache-Control

privatepublic,一次请求的实际过程可能极其复杂,通过各个节点,各个网关,private 和 public 就是告诉路上经过的这些中间节点是否需要帮助缓存信息。

️ private 并不表示内容的私密性,私密性是通过加密机制来实现的,它表示「个性化定制信息」。

REST

REST:对 HTTP 进行一种限制,属于一种架构风格。

RESTful HTTP

规范 HTTP 的使用方式,正确的使用 HTTP。

上一篇 下一篇

猜你喜欢

热点阅读