@ -360,9 +360,9 @@ console.log(document.cookie);
### 5. Secure 和 HttpOnly
标记为 Secure 的 Cookie 只应 通过被 HTTPS 协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过 Cookie 传输,因为 Cookie 有其固有的不安全性, Secure 标记也无法提供确实的安全保障。
标记为 Secure 的 Cookie 只能 通过被 HTTPS 协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过 Cookie 传输,因为 Cookie 有其固有的不安全性, Secure 标记也无法提供确实的安全保障。
标记为 HttpOnly 的 Cookie 不能被 JavaScript 脚本调用。因为 跨站脚本攻击 (XSS) 常常使用 JavaScript 的 `Document.cookie` API 窃取用户的 Cookie 信息,因此使用 HttpOnly 标记可以在一定程度上避免 XSS 攻击。
标记为 HttpOnly 的 Cookie 不能被 JavaScript 脚本调用。跨站脚本攻击 (XSS) 常常使用 JavaScript 的 `Document.cookie` API 窃取用户的 Cookie 信息,因此使用 HttpOnly 标记可以在一定程度上避免 XSS 攻击。
```html
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
@ -382,15 +382,15 @@ Path 标识指定了主机下的哪些路径可以接受 Cookie( 该 URL 路径
除了可以将用户信息通过 Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全。
Session 可以存储在服务器上的文件、数据库或者内存中。也可以将 Session 存储在内存型数据库中,比如 Redis。
Session 可以存储在服务器上的文件、数据库或者内存中。也可以将 Session 存储在内存型数据库中,比如 Redis,效率会更高 。
使用 Session 维护用户登录的过程如下:
- 用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;
- 服务器验证该用户名和密码;
- 如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 ID 称为 Session ID;
- 如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 Key 称为 Session ID;
- 服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID, 客户端收到响应报文之后将该 Cookie 值存入浏览器中;
- 客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID, 从 Redis 中取出用户信息,继续之后 的业务操作。
- 客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID, 从 Redis 中取出用户信息,继续之前 的业务操作。
应该注意 Session ID 的安全性问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的 Session ID 值。此外,还需要经常重新生成 Session ID。在对安全性要求极高的场景下, 例如转账等操作, 除了使用 Session 管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式。
@ -409,7 +409,7 @@ Session 可以存储在服务器上的文件、数据库或者内存中。也可
### 1. 优点
- 缓解服务器压力;
- 降低客户端获取资源的延迟(缓存资源比服务器上的资源离客户端更近) 。
- 降低客户端获取资源的延迟:缓存通常位于内存中,读取缓存的速度更快。并且缓存在地理位置上也有可能比源服务器来得近,例如浏览器缓存 。
### 2. 实现方法
@ -460,7 +460,10 @@ max-age 指令出现在响应报文中,表示缓存资源在缓存服务器中
Cache-Control: max-age=31536000
```
Expires 首部字段也可以用于告知缓存服务器该资源什么时候会过期。在 HTTP/1.1 中,会优先处理 Cache-Control : max-age 指令;而在 HTTP/1.0 中, Cache-Control : max-age 指令会被忽略掉。
Expires 首部字段也可以用于告知缓存服务器该资源什么时候会过期。
- 在 HTTP/1.1 中,会优先处理 max-age 指令;
- 在 HTTP/1.0 中, max-age 指令会被忽略掉。
```html
Expires: Wed, 04 Jul 2012 08:26:05 GMT
@ -496,13 +499,16 @@ If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
### 1. 短连接与长连接
当浏览器访问一个包含多张图片的 HTML 页面时,除了请求访问 HTML 页面资源,还会请求图片资源, 如果每进行一次 HTTP 通信就要断开一次 TCP 连接,连接建立和断开的开销会很大。长连接只需要建立一次 TCP 连接就能进行多次 HTTP 通信。
当浏览器访问一个包含多张图片的 HTML 页面时,除了请求访问 HTML 页面资源,还会请求图片资源。 如果每进行一次 HTTP 通信就要断开一次 TCP 连接,连接建立和断开的开销会很大。
从 HTTP/1.1 开始默认是长连接的,如果要断开连接,需要由客户端或者服务器端提出断开,使用 Connection : close; 而在 HTTP/1.1 之前默认是短连接的,如果需要长连接,则使用 Connection : Keep-Alive 。
长连接只需要建立一次 TCP 连接就能进行多次 HTTP 通信 。
- 从 HTTP/1.1 开始默认是长连接的,如果要断开连接,需要由客户端或者服务器端提出断开,使用 `Connection : close` ;
- 在 HTTP/1.1 之前默认是短连接的,如果需要使用长连接,则使用 `Connection : Keep-Alive` 。
### 2. 流水线
默认情况下, HTTP 请求是按顺序发出的,下一个请求只有在当前请求收到相 应之后才会被发出。由于会受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。
默认情况下, HTTP 请求是按顺序发出的,下一个请求只有在当前请求收到响 应之后才会被发出。由于会受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。
流水线是在同一条长连接上发出连续的请求,而不用等待响应返回,这样可以避免连接延迟。
@ -512,17 +518,17 @@ If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
### 1. 类型
** (一)服务端驱动型内容协商 **
** (一)服务端驱动型**
客户端设置特定的 HTTP 首部字段,例如 Accept、Accept-Charset、Accept-Encoding、Accept-Language、Content-Languag, 服务器根据这些字段返回特定的资源。
它存在以下问题:
- 服务器很难知道客户端浏览器的全部信息;
- 客户端提供的信息相当冗长( HTTP/2 协议的首部压缩机制缓解了这个问题) , 并且存在隐私风险( HTTP 指纹识别技术)。
- 客户端提供的信息相当冗长( HTTP/2 协议的首部压缩机制缓解了这个问题) , 并且存在隐私风险( HTTP 指纹识别技术);
- 给定的资源需要返回不同的展现形式,共享缓存的效率会降低,而服务器端的实现会越来越复杂。
** (二)代理驱动型协商 **
** (二)代理驱动型**
服务器返回 300 Multiple Choices 或者 406 Not Acceptable, 客户端从中选出最合适的那个资源。
@ -538,9 +544,11 @@ Vary: Accept-Language
## 内容编码
内容编码将实体主体进行压缩,从而减少传输的数据量。常用的内容编码有: gzip、compress、deflate、identity。
内容编码将实体主体进行压缩,从而减少传输的数据量。
浏览器发送 Accept-Encoding 首部,其中包含有它所支持的压缩算法,以及各自的优先级,服务器则从中选择一种,使用该算法对响应的消息主体进行压缩,并且发送 Content-Encoding 首部来告知浏览器它选择了哪一种算法。由于该内容协商过程是基于编码类型来选择资源的展现形式的, 在响应中, Vary 首部中至少要包含 Content-Encoding, 这样的话, 缓存服务器就可以对资源的不同展现形式进行缓存 。
常用的内容编码有: gzip、compress、deflate、identity 。
浏览器发送 Accept-Encoding 首部,其中包含有它所支持的压缩算法,以及各自的优先级。服务器则从中选择一种,使用该算法对响应的消息主体进行压缩,并且发送 Content-Encoding 首部来告知浏览器它选择了哪一种算法。由于该内容协商过程是基于编码类型来选择资源的展现形式的,在响应的 Vary 首部至少要包含 Content-Encoding。
## 范围请求
@ -622,10 +630,14 @@ HTTP/1.1 使用虚拟主机技术,使得一台服务器拥有多个域名,
- 网络访问控制
- 访问日志记录
代理服务器分为正向代理和反向代理两种,用户察觉得到正向代理的存在;而反向代理一般位于内部网络中,用户察觉不到。
代理服务器分为正向代理和反向代理两种:
- 用户察觉得到正向代理的存在。
< div align = "center" > < img src = "../pics//a314bb79-5b18-4e63-a976-3448bffa6f1b.png" width = "" /> </ div >< br >
- 而反向代理一般位于内部网络中,用户察觉不到。
< div align = "center" > < img src = "../pics//2d09a847-b854-439c-9198-b29c65810944.png" width = "" /> </ div >< br >
### 2. 网关
@ -634,7 +646,7 @@ HTTP/1.1 使用虚拟主机技术,使得一台服务器拥有多个域名,
### 3. 隧道
使用 SSL 等加密手段,为 客户端和服务器之间建立一条安全的通信线路。
使用 SSL 等加密手段,在 客户端和服务器之间建立一条安全的通信线路。
# 六、HTTPs
@ -644,7 +656,7 @@ HTTP 有以下安全性问题:
- 不验证通信方的身份,通信方的身份有可能遭遇伪装;
- 无法证明报文的完整性,报文有可能遭篡改。
HTTPs 并不是新协议,而是让 HTTP 先和 SSL( Secure Sockets Layer) 通信, 再由 SSL 和 TCP 通信。 也就是说 HTTPs 使用了隧道进行通信。
HTTPs 并不是新协议,而是让 HTTP 先和 SSL( Secure Sockets Layer) 通信, 再由 SSL 和 TCP 通信, 也就是说 HTTPs 使用了隧道进行通信。
通过使用 SSL, HTTPs 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。
@ -727,7 +739,11 @@ HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式
< div align = "center" > < img src = "../pics//86e6a91d-a285-447a-9345-c5484b8d0c47.png" width = "400" /> </ div >< br >
在通信过程中,只会有一个 TCP 连接存在, 它承载了任意数量的双向数据流( Stream) 。一个数据流都有一个唯一标识符和可选的优先级信息, 用于承载双向信息。消息( Message) 是与逻辑请求或响应消息对应的完整的一系列帧。帧( Fram) 是最小的通信单位, 来自不同数据流的帧可以交错发送, 然后再根据每个帧头的数据流标识符重新组装。
在通信过程中,只会有一个 TCP 连接存在, 它承载了任意数量的双向数据流( Stream) 。
- 一个数据流都有一个唯一标识符和可选的优先级信息,用于承载双向信息。
- 消息( Message) 是与逻辑请求或响应消息对应的完整的一系列帧。
- 帧( Fram) 是最小的通信单位, 来自不同数据流的帧可以交错发送, 然后再根据每个帧头的数据流标识符重新组装。
< div align = "center" > < img src = "../pics//af198da1-2480-4043-b07f-a3b91a88b815.png" width = "600" /> </ div >< br >
@ -739,7 +755,11 @@ HTTP/2.0 在客户端请求一个资源时,会把相关的资源一起发送
## 首部压缩
HTTP/1.1 的首部带有大量信息,而且每次都要重复发送。HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见过的首部字段表, 从而避免了重复传输。不仅如此, HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩。
HTTP/1.1 的首部带有大量信息,而且每次都要重复发送。
HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见过的首部字段表,从而避免了重复传输。
不仅如此, HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩。
< div align = "center" > < img src = "../pics//_u4E0B_u8F7D.png" width = "600" /> </ div >< br >
@ -751,7 +771,9 @@ GET 用于获取资源,而 POST 用于传输实体主体。
## 参数
GET 和 POST 的请求都能使用额外的参数,但是 GET 的参数是以查询字符串出现在 URL 中,而 POST 的参数存储在实体主体中。
GET 和 POST 的请求都能使用额外的参数,但是 GET 的参数是以查询字符串出现在 URL 中,而 POST 的参数存储在实体主体中。不能因为 POST 参数存储在实体主体中就认为它的安全性更高, 因为照样可以通过一些抓包工具( Fiddler) 查看。
因为 URL 只支持 ASCII 码,因此 GET 的参数中如果存在中文等字符就需要先进行编码。例如 `中文` 会转换为 `%E4%B8%AD%E6%96%87` ,而空格会转换为 `%20` 。POST 参考支持标准字符集。
```
GET /test/demo_form.asp?name1=value1&name2=value2 HTTP/1.1
@ -763,10 +785,6 @@ Host: w3schools.com
name1=value1&name2=value2
```
不能因为 POST 参数存储在实体主体中就认为它的安全性更高, 因为照样可以通过一些抓包工具( Fiddler) 查看。
因为 URL 只支持 ASCII 码,因此 GET 的参数中如果存在中文等字符就需要先进行编码,例如`中文` 会转换为`%E4%B8%AD%E6%96%87` ,而空格会转换为`%20` 。POST 支持标准字符集。
## 安全
安全的 HTTP 方法不会改变服务器状态,也就是说它只是可读的。
@ -779,9 +797,13 @@ GET 方法是安全的,而 POST 却不是,因为 POST 的目的是传送实
## 幂等性
幂等的 HTTP 方法,同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。在正确实现的条件下, GET, HEAD, PUT 和 DELETE 等方法都是幂等的,而 POST 方法不是。所有的安全方法也都是幂等的。
幂等的 HTTP 方法,同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。
GET /pageX HTTP/1.1 是幂等的。连续调用多次,客户端接收到的结果都是一样的:
所有的安全方法也都是幂等的。
在正确实现的条件下, GET, HEAD, PUT 和 DELETE 等方法都是幂等的,而 POST 方法不是。
GET /pageX HTTP/1.1 是幂等的,连续调用多次,客户端接收到的结果都是一样的:
```
GET /pageX HTTP/1.1
@ -790,7 +812,7 @@ GET /pageX HTTP/1.1
GET /pageX HTTP/1.1
```
POST /add_row HTTP/1.1 不是幂等的。 如果调用多次,就会增加多行记录:
POST /add_row HTTP/1.1 不是幂等的, 如果调用多次,就会增加多行记录:
```
POST /add_row HTTP/1.1 -> Adds a 1nd row
@ -820,7 +842,8 @@ DELETE /idX/delete HTTP/1.1 -> Returns 404
> XMLHttpRequest 是一个 API, 它为客户端提供了在客户端和服务器之间传输数据的功能。它提供了一个通过 URL 来获取数据的简单方式, 并且不会使整个页面刷新。这使得网页只更新一部分页面而不会打扰到用户。XMLHttpRequest 在 AJAX 中被大量使用。
在使用 XMLHttpRequest 的 POST 方法时,浏览器会先发送 Header 再发送 Data。但并不是所有浏览器会这么做, 例如火狐就不会。而 GET 方法 Header 和 Data 会一起发送。
- 在使用 XMLHttpRequest 的 POST 方法时,浏览器会先发送 Header 再发送 Data。但并不是所有浏览器会这么做, 例如火狐就不会。
- 而 GET 方法 Header 和 Data 会一起发送。
# 九、HTTP/1.0 与 HTTP/1.1 的区别