HTTP 是什么?
Hyper Text Transfer Protocol 超文本传输协议,是一种 Client 和 Server 之间请求和应答的标准,目的是更高效的进行网络传输。
HTTP 工作方式
用户最直观的感受就是浏览器地址栏键入地址->回车->看到浏览器呈现的网页,这个过程简单的流程就是:
浏览器发送请求到服务器,服务器响应请求,浏览器通过渲染引擎渲染网页结果,渲染引擎也就是浏览器的内核。

示例地址:https://twitter.com/shaddeen_/followers
shaddeen,是小众音乐播放器 Loud 和 SmartPlayer 的作者。
所以在这个从按下回车到直观看到界面的过程就简单的概括为 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为一个请求行,分三个部分:
- GET 为 请求 method;
- /shaddeen_/followers 为 path,负责定位;
- HTTP/1.1 为 HTTP Version,现在绝大多数的浏览器的网页显示 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 亦分为三个部分:
- HTTP/1.1 HTTP 版本;
- 200 status code 状态码;
- OK status message 状态信息。
这三部分的组合可以简单地描述一次请求。
Request Method
- GET 获取资源,无 body,简单的来说就是从网上取东西;
- POST 增加或修改资源,有 body,要把修改的内容放进 body 里给服务器进行处理;
- PUT 修改资源, 有 body,它和 GET 有个共同的特点就是幂等(一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同,在这里指多次操作对于服务器没有影响)的;
- DELETE 删除资源,无 body,同样具有幂等性;
- HEAD 几乎和 GET 是一样的,区别在于服务器返回内容的时候不会返回 body,当做下载功能的时候通常需要预先知道该文件有多大或更多的信息,此时 HEAD 通过请求会得到这些信息,然后再进行一步处理。
Status Code
作用:对结果作出类型化描述(如「成功」、「未找到」)。
通常规范化的状态码有 5 类,分类是为了方便调试:
- 1xx: 临时性消息,通常为 100 和 101。100,表示初始的请求已经接受,客户端可以接着进行下面的请求,如上传一个大文件,在试探性请求服务器的过程中,会把一些描述信息放进 Header 中与服务器沟通试探服务器是否接受,如服务器返回 100 则客户端可以进行下面的操作。101 表示服务器回应客户端「支持 HTTP/2.0」,此时客户端下一次的请求就可以切换为为 HTTP/2.0,当不支持 HTTP/2.0 的时候会返回 200,那么客户端下一次请求则使用 HTTP/1.1 ;
- 2xx: 成功;
- 3xx: 重定向,如地址栏键入 http://www.google.com ,浏览器会重定向到 https://www.google.com ,该过程是一个自动的二次请求过程,就是通过返回的 301 (Moved Permanently 永久性迁移, 302 为临时迁移,304 表示内容没有改变,F5 重新刷新该网页)状态码来告诉客户端重新请求;
- 4xx: 客户端(浏览器、手机软件)错误,如参数错误,服务器无法识别该请求,是可以修正的;
- 5xx: 服务器错误,如资源不足、资源找不到。
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-Length:内容的长度(字节)
为什么会有 Content-Type 的存在?
是因为请求报文中,可能会携带二进制非文本数据,二进制数据本身是不受限制的,它表示着各种各样的字节,那么如何表示内容字节结束?此时 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:缓存,表示一块内容可能多次使用,所以这部分内容暂时放在缓存区域中,当不用的时候会被回收掉,面向速度;
- Buffer: 缓冲,工作过程中,上游生产快下游不能及时消费,或者下游暂时无消费,时间段过后会「猛」消费,则需要缓冲机制,提前生产一点存起来供下游使用,面向工作流;
Cache-Control
no-cache、no-store、max-age:
- no-cache: 服务器告诉 Client 端,该内容可以缓存,但是再次请求的时候服务器需要知道缓存的内容是否失效;
- no-store: 不许缓存;
- max-age: 在失效日期内,Client 端随意访问;
Last-Modified
If-Modified-Since: 缓存界面最后的修改时间,请求过程中,服务器会对比缓存的最后修改时间和真实文件的最后修改时间,如果一致,说明文件没有改动过,返回 304,否则返回 200 和新的内容。
Etag
If-None-Match: 相当于 Hash,或者说相当于一个指纹,Client 端也可凭借该字段与服务器「沟通」,对比这个标签,如果不是最新的,则请求最新的,返回 200 显示新内容,如果一致,则 返回 304。
Cache-Control
private 和 public,一次请求的实际过程可能极其复杂,通过各个节点,各个网关,private 和 public 就是告诉路上经过的这些中间节点是否需要帮助缓存信息。
️ private 并不表示内容的私密性,私密性是通过加密机制来实现的,它表示「个性化定制信息」。
REST
REST:对 HTTP 进行一种限制,属于一种架构风格。
- Server-Client architecture
- Statelessness
- Cacheability
- Layered system
- Code on demand
- Uniform interface
- Resource identification in requests
- Resource manipulation through representations
- Self-descriptive messages
- Hypermedia as the engine of application state (HATEOAS)
RESTful HTTP
规范 HTTP 的使用方式,正确的使用 HTTP。
网友评论