Skip to content

Commit 25d4bf8

Browse files
author
Tan Minghui
committed
Update HTTP 协议.md
1 parent 8260fd0 commit 25d4bf8

File tree

1 file changed

+180
-32
lines changed

1 file changed

+180
-32
lines changed

net/HTTP 协议.md

Lines changed: 180 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ HTTP1.x 为了解决效率问题,可能会尽量多的发起并发的请求去
6969

7070
服务器端推送的这些资源其实存在客户端的某处地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然是快很多的。
7171

72-
## 模型
7372

74-
四层模型
73+
74+
## 模型
7575

7676
- 应用层(HTTP)
7777
- 传输层(TCP)
@@ -80,7 +80,7 @@ HTTP1.x 为了解决效率问题,可能会尽量多的发起并发的请求去
8080

8181

8282

83-
## HTTP 协议
83+
## 报文格式
8484

8585
### 请求报文
8686

@@ -104,8 +104,8 @@ Content-Length: 136
104104
```
105105

106106
1. 起始行
107-
2. 表头
108-
3. 内容**(可选)**
107+
2. 首部
108+
3. 主体**(可选)**
109109

110110
`GET`, `HEAD`, `DELETE` `OPTIONS` 这些请求方法不需要请求内容。
111111

@@ -120,28 +120,33 @@ HTTP-message = start-line <-- -- 在這!
120120
[ message-body ]
121121
```
122122

123-
- HTTP 方法(如 GET, POST, PUT...)
124-
- 目标 URL
125-
- HTTP 版本
123+
HTTP请求是由客户端发出的消息,用来使服务器执行动作。*起始行 (start-line)* 包含三个元素:
126124

125+
1. 一个 *HTTP 方法*,一个动词 (像 [`GET`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/GET), [`PUT`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/PUT) 或者 [`POST`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/POST)) 或者一个名词 (像 [`HEAD`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/HEAD) 或者 [`OPTIONS`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/OPTIONS)), 描述要执行的动作.
126+
2. *请求目标 (request target),*通常是一个 [URL](https://developer.mozilla.org/en-US/docs/Glossary/URL),或者是协议、端口和域名的绝对路径,通常以请求的环境为特征。请求的格式因不同的 HTTP 方法而异。
127+
3. *HTTP 版本 (HTTP version*)**定义了剩余报文的结构,作为对期望的响应版本的指示符。
127128

128129

129-
**表头**
130130

131-
單個 表頭欄位 (header-field) 的組成 :
131+
**首部**
132132

133-
- 一個 不區分大小寫的 欄位名稱 (field-name) — — 習慣上仍以首字大寫為主
134-
- 緊接一個 冒號 (colon ":")
135-
- 可選的空白 (optional trailing whitespace, OWS)
136-
- 欄位值 (field-value)
137-
- 可選的空白 (optional trailing whitespace, OWS)
133+
有许多请求头可用,它们可以分为几组:
138134

139-
```
140-
header-field = field-name ":" OWS field-value OWS
141-
```
135+
- 通用首部(*General headers*),例如 [`Via`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Via),适用于整个报文。
136+
- 请求首部(*Request headers*)例如 [`User-Agent`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/User-Agent)[`Accept-Type`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Type),通过进一步的定义(例如 [`Accept-Language`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Language)),或者给定上下文(例如 [`Referer`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer)),或者进行有条件的限制 (例如 [`If-None`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/If-None)) 来修改请求。
137+
- 实体首部(*Entity headers*),例如 [`Content-Length`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Length),适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。
142138

143139

144140

141+
**内容**
142+
143+
请求的最后一部分是它的 body。不是所有的请求都有一个 body:例如获取资源的请求,GET,HEAD,DELETE 和 OPTIONS,通常它们不需要 body。 有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST 请求(包含 HTML 表单数据)。
144+
145+
Body 大致可分为两类:
146+
147+
- Single-resource bodies,由一个单文件组成。该类型 body 由两个 header 定义: [`Content-Type`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type)[`Content-Length`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Length).
148+
- [Multiple-resource bodies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#multipartform-data),由多部分 body 组成,每一部分包含不同的信息位。通常是和 [HTML Forms](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms) 连系在一起。
149+
145150

146151

147152
### 响应报文
@@ -163,24 +168,44 @@ Connection: Close
163168
```
164169

165170
1. 状态行
171+
2. 首部
172+
3. 主体
173+
174+
175+
176+
**状态行**
177+
178+
HTTP 响应的起始行被称作 *状态行* *(status line)*,包含以下信息:
179+
180+
1. *协议版本*,通常为 `HTTP/1.1。`
181+
2. *状态码 (**status code)*,表明请求是成功或失败。常见的状态码是 [`200`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/200)[`404`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/404),或 [`302`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/302)
182+
3. *状态文本 (status text)*。一个简短的,纯粹的信息,通过状态码的文本描述,帮助人们理解该 HTTP 消息。
183+
184+
一个典型的状态行看起来像这样:`HTTP/1.1 404 Not Found。`
185+
186+
187+
188+
**首部**
189+
190+
有许多响应头可用,这些响应头可以分为几组:
166191

167-
- HTTP 协议
168-
- 状态码
169-
- 状态描述
192+
- 通用首部(*General headers*),例如 [`Via`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Via),适用于整个报文。
193+
- 响应首部(*Response headers*)例如 [`Vary`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Vary)[`Accept-Ranges`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Ranges),提供其它不符合状态行的关于服务器的信息。
194+
- 实体首部(*Entity headers*),例如 [`Content-Length`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Length),适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。
170195

171-
例子 `HTTP/1.1 404 Not Found`.
172196

173-
2. 头部
174197

175-
- General headers
176-
- Reponse headers
177-
- Entity Headers
198+
**内容**
178199

179-
3. 内容
200+
Body 大致可分为三类:
180201

202+
- Single-resource bodies,由**已知**长度的单个文件组成。该类型 body 由两个 header 定义:[`Content-Type`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type)[`Content-Length`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Length)
203+
- Single-resource bodies,由**未知**长度的单个文件组成,通过将 [`Transfer-Encoding`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Transfer-Encoding) 设置为 `chunked 来`使用 chunks 编码。
204+
- [Multiple-resource bodies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#multipartform-data),由多部分 body 组成,每部分包含不同的信息段。但这是比较少见的。
181205

182206

183207

208+
**例子**
184209

185210
```html
186211
HTTP/1.1 200 OK
@@ -191,22 +216,145 @@ Content-Type: text/html
191216

192217

193218

219+
### 通用首部字段
220+
221+
- Cache-control
222+
- Connection
223+
- Date
224+
- Pragma
225+
- Trailer
226+
- Transfer-Encoding
227+
- Upgrade
228+
- Via
229+
- Warning
230+
231+
232+
233+
## HTTP 缓存
234+
235+
| 指令 | 说明 |
236+
| --------------- | ---------------------------- |
237+
| no-cache | 强制向源服务器再次验证 |
238+
| no-store | 不缓存请求或响应的任何内容 |
239+
| max-age | 响应的最大Age值 |
240+
| max-stale | 接收已过期的响应 |
241+
| min-fresh | 期望在指定时间内的响应仍有效 |
242+
| no-transform | 代理不可更改媒体类型 |
243+
| only-if-cached | 从缓存获取资源 |
244+
| cache-extension | 新指令标记(token) |
245+
246+
247+
248+
### Expires
249+
250+
```
251+
Expires: Wed, 21 Oct 2017 07:28:00 GMT
252+
```
253+
254+
瀏覽器收到這個 Response 之後就會把這個資源給快取起來,當下一次使用者再度造訪這個頁面或是要求這個圖片的資源的時候,瀏覽器會檢視「現在的時間」是否有超過這個 Expires。如果沒有超過的話,那瀏覽器「不會發送任何 Request」,而是直接從電腦裡面已經存好的 Cache 拿資料。
255+
256+
### Control 与 max-age
257+
258+
Expires 其實是 HTTP 1.0 就存在的 Header,而為了解決上面 Expires 會碰到的問題,HTTP 1.1 有一個新的 header 出現了,叫做:`Cache-Control`。(註:Cache-Control 是 HTTP 1.1 出現的 Header,但其實不單單只是解決這個問題,還解決許多 HTTP 1.0 沒辦法處理的快取相關問題)
259+
260+
`max-age`會蓋過`Expires`。因此現在的快取儘管兩個都會放,但其實真正會用到的是`max-age`
261+
262+
**Last-Modified 與 If-Modified-Since**
263+
264+
想要做到上面的功能,必須要 Server 跟 Client 兩邊互相配合才行。其中一種做法就是使用 HTTP 1.0 就有的:`Last-Modified``If-Modified-Since`的搭配使用。
265+
266+
```
267+
Last-Modified: 2017-01-01 13:00:00
268+
Cache-Control: max-age=31536000
269+
```
270+
271+
假設沒有更新的話,Server 就會回一個`Status code: 304 (Not Modified)`,代表你可以繼續沿用快取的這份檔案。
272+
273+
**Etag 與 If-None-Match**
274+
275+
`Etag`這個 Header 就是這樣的一個東西。你可以把 Etag 想成是這份檔案內容的 hash 值(但其實不是,但原理類似就是了,總之就是一樣的內容會產生一樣的 hash,不一樣的會產生不一樣的 hash)。
276+
277+
在 Response 裡面 Server 會帶上這個檔案的 Etag,等快取過期之後,瀏覽器就可以拿這個 Etag 去問說檔案是不是有被更動過。
278+
279+
`Etag``If-None-Match`也是搭配使用的一對,就像`Last-Modified``If-Modified-Since`一樣。
280+
281+
![img](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/images/http-cache-control.png?hl=zh-tw)
282+
283+
**强 ETag 值和弱 Tag 值**
284+
ETag 中有强 ETag 值和弱 ETag 值之分。
285+
286+
- 强 ETag 值,不论实体发生多么细微的变化都会改变其值。
287+
288+
```
289+
ETag: "usagi-1234"
290+
```
291+
292+
- 弱 ETag 值只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变 ETag 值。这时,会在字段值最开始处附加 W/。
293+
294+
```
295+
ETag: W/"usagi-1234"
296+
```
297+
298+
299+
300+
**Cache 策略**
301+
302+
除了可以指定`max-age`以外,可以直接使用:`Cache-Control: no-store`,代表說:「我就是不要任何快取」。
303+
304+
`Cache-Control: no-cache``no-cache`並不是「完全不使用快取的意思」。no-cache 代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源,也许称为 do-notserve-from-cache-without-revalidation 更合适。
305+
306+
307+
308+
## Cookie
309+
310+
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,**浏览器把请求的网址连同该Cookie一同提交给服务器**。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
311+
312+
[]: https://www.cnblogs.com/lingyejun/p/9282169.html "什么是Http无状态?Session、Cookie、Token三者之间的区别"
313+
314+
315+
316+
## Session
317+
318+
- Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。
319+
- 客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
320+
- 如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。
321+
- Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
322+
323+
### Session 与 Cookie 之间的关系
324+
325+
- cookie 是一个**实际存在的、具体的东西**,http 协议中定义在 header 中的字段。
326+
- session 是一个抽象概念、开发者为了实现中断和继续等操作,将client和server之间一对一的交互,抽象为“会话”,进而衍生出“会话状态”,也就是 session 的概念。
327+
- 即session描述的是一种通讯会话机制,而cookie只是目前实现这种机制的主流方案里面的一个参与者,它一般是用于保存session ID。
328+
329+
参考资料:
330+
331+
[]: http://fred-zone.blogspot.com/2014/01/web-session.html "Web 技術中的 Session 是什麼?"
332+
333+
194334

335+
## Token
195336

196-
## TCP 协议
337+
![img](https://user-gold-cdn.xitu.io/2017/6/1/02d484cc1f675ec36e96b8899d756b31?imageView2/0/w/1280/h/960/format/webp/ignore-error/1)
197338

198-
- 将消息分割为不同报文段
199-
- 三次握手
339+
Token 和 Session 有一点不相同,Session 内容需要保存在服务端,但是 **Token 不需要保存在服务端**
200340

341+
服务端向客户端返回数据时,根据只有服务器自己才知道的密钥,会在数据里面加一个「签名」。由于其他人不知道密钥,所以 Token 无法被伪造。
201342

343+
而且这个`Token`不需要保存在服务端,当客户端重新将`Token`发送到服务器时,服务端会使用相同的加密算法和密钥,对数据重新计算一次签名,然后与`Token`进行比较。相同的话,证明数据没有被篡改。
202344

203-
## IP 协议
345+
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
204346

205-
- 路由寻址
347+
1. 客户端使用用户名跟密码请求登录
348+
2. 服务端收到请求,去验证用户名与密码
349+
3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
350+
4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
351+
5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
352+
6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
206353

207354

208355

209356
------
210357

211358
[]: https://developer.mozilla.org/zh-CN/docs/Web/HTTP "HTTP"
359+
[]: https://blog.techbridge.cc/2017/06/17/cache-introduction/ "循序漸進理解 HTTP Cache 機制"
212360

0 commit comments

Comments
 (0)