@@ -69,9 +69,9 @@ HTTP1.x 为了解决效率问题,可能会尽量多的发起并发的请求去
69
69
70
70
服务器端推送的这些资源其实存在客户端的某处地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然是快很多的。
71
71
72
- ## 模型
73
72
74
- 四层模型
73
+
74
+ ## 模型
75
75
76
76
- 应用层(HTTP)
77
77
- 传输层(TCP)
@@ -80,7 +80,7 @@ HTTP1.x 为了解决效率问题,可能会尽量多的发起并发的请求去
80
80
81
81
82
82
83
- ## HTTP 协议
83
+ ## 报文格式
84
84
85
85
### 请求报文
86
86
@@ -104,8 +104,8 @@ Content-Length: 136
104
104
```
105
105
106
106
1 . 起始行
107
- 2 . 表头
108
- 3 . 内容 ** (可选)**
107
+ 2 . 首部
108
+ 3 . 主体 ** (可选)**
109
109
110
110
` GET ` , ` HEAD ` , ` DELETE ` ` OPTIONS ` 这些请求方法不需要请求内容。
111
111
@@ -120,28 +120,33 @@ HTTP-message = start-line <-- -- 在這!
120
120
[ message-body ]
121
121
```
122
122
123
- - HTTP 方法(如 GET, POST, PUT...)
124
- - 目标 URL
125
- - HTTP 版本
123
+ HTTP请求是由客户端发出的消息,用来使服务器执行动作。* 起始行 (start-line)* 包含三个元素:
126
124
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* )* ,* 定义了剩余报文的结构,作为对期望的响应版本的指示符。
127
128
128
129
129
- ** 表头**
130
130
131
- 單個 表頭欄位 (header-field) 的組成 :
131
+ ** 首部 **
132
132
133
- - 一個 不區分大小寫的 欄位名稱 (field-name) — — 習慣上仍以首字大寫為主
134
- - 緊接一個 冒號 (colon ":")
135
- - 可選的空白 (optional trailing whitespace, OWS)
136
- - 欄位值 (field-value)
137
- - 可選的空白 (optional trailing whitespace, OWS)
133
+ 有许多请求头可用,它们可以分为几组:
138
134
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,则不会发送这样的头文件。
142
138
143
139
144
140
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
+
145
150
146
151
147
152
### 响应报文
@@ -163,24 +168,44 @@ Connection: Close
163
168
```
164
169
165
170
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
+ 有许多响应头可用,这些响应头可以分为几组:
166
191
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,则不会发送这样的头文件。
170
195
171
- 例子 ` HTTP/1.1 404 Not Found ` .
172
196
173
- 2 . 头部
174
197
175
- - General headers
176
- - Reponse headers
177
- - Entity Headers
198
+ ** 内容**
178
199
179
- 3 . 内容
200
+ Body 大致可分为三类:
180
201
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 组成,每部分包含不同的信息段。但这是比较少见的。
181
205
182
206
183
207
208
+ ** 例子**
184
209
185
210
``` html
186
211
HTTP/1.1 200 OK
@@ -191,22 +216,145 @@ Content-Type: text/html
191
216
192
217
193
218
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
+
194
334
335
+ ## Token
195
336
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 )
197
338
198
- - 将消息分割为不同报文段
199
- - 三次握手
339
+ Token 和 Session 有一点不相同,Session 内容需要保存在服务端,但是 ** Token 不需要保存在服务端** 。
200
340
341
+ 服务端向客户端返回数据时,根据只有服务器自己才知道的密钥,会在数据里面加一个「签名」。由于其他人不知道密钥,所以 Token 无法被伪造。
201
342
343
+ 而且这个` Token ` 不需要保存在服务端,当客户端重新将` Token ` 发送到服务器时,服务端会使用相同的加密算法和密钥,对数据重新计算一次签名,然后与` Token ` 进行比较。相同的话,证明数据没有被篡改。
202
344
203
- ## IP 协议
345
+ 使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
204
346
205
- - 路由寻址
347
+ 1 . 客户端使用用户名跟密码请求登录
348
+ 2 . 服务端收到请求,去验证用户名与密码
349
+ 3 . 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
350
+ 4 . 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
351
+ 5 . 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
352
+ 6 . 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
206
353
207
354
208
355
209
356
------
210
357
211
358
[ ] : https://developer.mozilla.org/zh-CN/docs/Web/HTTP "HTTP"
359
+ [ ] : https://blog.techbridge.cc/2017/06/17/cache-introduction/ "循序漸進理解 HTTP Cache 機制"
212
360
0 commit comments