体系结构#
功能#
- 数据通信
- 资源共享
- 分布式处理
- 提高可靠性
- 负载均衡
分类#
分布范围
- 广域网
- 城域网
- 局域网
- 个人区域网
技术分类
- 广播式网络
- 点对点网络
物理层#
数据链路层#
网络层#
IP 协议#
传输层#
TCP 协议#
首部#
20 个字节
UDP 协议#
特点:
- 无连接的
- 不保证可靠交付
- 面向报文的
- 没有拥塞控制
首部#
8 个字节
单播、多播和广播#
单博#
一对一通信
多播(组播)#
消息只是发送到一个多播地址,网络将数据分发给哪些表示想要接收发送到该多播地址的数据的主机
ASM(Any-Source Multicast,任意源组播)
SSM(Source-Specific Multicast,指定源组播)
SFM(Source-Filtered Multicast,过滤源的组播)
广播#
网络中的所有主机都会接收一份数据副本
使用广播地址:255.255.255.255
需要指明接收者的端口号
应用层#
HTTP 协议#
四种常见的 POST 提交数据方式:https://imququ.com/post/four-ways-to-post-data-in-http.html
谈谈 form-data 请求格式:https://www.cnblogs.com/wonyun/p/7966967.html
Multipart/form-data POST 文件上传详解:https://blog.csdn.net/xiaojianpitt/article/details/6856536
POST 之 multipart/form-data 请求:https://www.jianshu.com/p/0023bb7afddb
multipart/form-data (一种 POST 数据提交的方式):https://blog.csdn.net/dreamerrrrrr/article/details/111146763
大小写问题#
HTTP Header 的名称字段是不区分大小写的。
HTTP Header 的名称字段是不区分大小写的。
HTTP 协议 (scheme / protocol) 和域名 (host) 不区分大小写,但 path、query、fragment 是区分的。
默认可以认为是区分的,主流浏览器 Chrome 与 FireFox 的实现也都是区分 Cookie 的大小写。
cookie#
cookie domin 导致的优先级问题: https://blog.csdn.net/yy19900806/article/details/79190933
Set-Cookie:
header 中 Set-Cookie 可以重复
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnlyid=a3fWa 为 cookie
Expires=Wed, 21 Oct 2015 07:28:00 GMT 为过期时间
Secure 只允许 HTTPS
HttpOnly 不允许 JavaScript 的 Document.cookie API 访问
Domain=mozilla.org 指定哪些主机可以接受 Cookie,如果不指定,该属性默认为同一 host 设置 cookie,不包含子域名。如果指定了 Domain,则一般包含子域名。
Path=/docs 指定了一个 URL 路径,该 URL 路径必须存在于请求的 URL中
SameSite=Lax 使用 Strict,cookie 仅发送到它来源的站点。Lax 与 Strict 相似,只是在用户导航到 cookie 的源站点时发送 cookie。例如,通过跟踪来自外部站点的链接。None 指定浏览器会在同站请求和跨站请求下继续发送 cookie,但仅在安全的上下文中(即,如果 SameSite=None,且还必须设置 Secure 属性)。如果没有设置 SameSite 属性,则将 cookie 视为 Lax.
Cookie:
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
HTTP/1.x 的连接管理#

短连接#
HTTP 最早期的模型,也是 HTTP/1.0 的默认模型,是短连接。
长连接#
缺点:
效率比较低,因为它是半双工的(发送和接受只能同时做一个,协议要么是发送状态,要么是接受状态)。
流水线#
缺点:
低效率的全双工模式,请求和响应顺序必须完全相同,而且请求和响应都还是单向串行的。会造成线头阻塞,有两个场景:
- 服务器处理一个请求太慢,即使把第二个请求也发送过去了,第二个请求比第一个请求先 ready 了,这个响应也不能发送,需要等到第一个完成后才行。(如果有个序号机制,可以解决一下)
- 服务器响应不慢,但是第一个请求太大了,传输很慢。这样即使第二个请求很小,但是还是得等第一个传输完了。(序号机制也不行)
所以在 HTTP2 把多个请求流塞到一个 TCP 连接里面,这样的连接复用方式就提高了效率,又节省了连接握手。需要注意 HTTP2 没有完全解决线头阻塞问题,因为实际中 TCP 的连接buffer 有限,一个响应又慢,又大的请求会把 buffer 完全占满,导致 buffer 阻塞,从而导致跟线头阻塞一样的效果。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Connection_management_in_HTTP_1.x
web socket#
已转移到: Web Socket
WebScoket 是一种在单个 TCP 连接上进行全双工通信的协议。
首先还是由客户端发起 HTTP 请求,经过 3 次握手后,建立起 TCP 连接,HTTP 请求里存放了 WebScoket 支持的版本号等信息,如: Upgrade、Connect、WebScoket-Version 等,其中还有一个请求头 Sec-WebScoket-Key,这是客户端使用 base64 编码的 24 位随机字符序列,用于服务器标识当前连接的客户端,同时也要求服务器响应一个同样加密的 Sec-WebScoket-Accept 头作为应答,这个用于给客户端标识当前连接的服务器,只有当两者匹配,连接才算建立成功(服务器响应101状态码表示连接成功),最后借助于 TCP 传输信道进行全双工通信。
特点
- 没有同源限制
第一次通过,http 升级到 web socket
//可选的客户端支持的协议扩展列表,指示了客户端希望使用的协议级别的扩展Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
//自动生成的key,已验证服务器对协议的支持,其值必须是Sec-WebSocket-Key: RfbP3GpmZpMiUaAfex5JRQ==
//可选的应用指定的子协议列表(可以是多个,用“,”分割)Sec-WebSocket-Protocol: mqtt
//客户端使用的websocket协议版本Sec-WebSocket-Version: 13
- FIN:0 表示不是最后一帧,1 表示最后一帧
- RSV1,RSV2,RSV3:一般情况下全为0。当客户端、服务端协商采用 WebSocket 扩展时,这三个标志位可以非 0,且值的含义由扩展进行定义。如果出现非零的值且并没有采用 WebSocket 扩展,连接出错
- 操作码(Opcode):
- %x0:表示一个延续帧。当 Opcode 为 0 时,表示本次数据传输采用了数据分片,当前收到的数据帧为其中一个数据分片
- %x1:表示一个文本帧(text frame)
- %x2:表示一个二进制帧(binary frame)
- %x3-7:保留的操作代码,用于后续定义的非控制帧
- %x8:表示连接断开
- %x9:表示这是一个心跳请求(ping)
- %xA(%x10):表示这是一个心跳响应(pong)
- %xB-F:保留的操作代码,用于后续定义的控制帧
- 掩码(Mask) 表示是否对数据载荷进行掩码异或操作。1表示需要,0表示不需要。只适用于客户端给服务器的消息,客户端给服务器发送消息,这里一定为1
参考 https://blog.csdn.net/sermonlizhi/article/details/118609757
keep-alive#
Keep-Alive 模式发送完数据 HTTP 服务器不会自动断开连接,不能再使用返回 EOF(-1)来判断响应数据已经接收完成,它通过下面的两种方式来判断。
- 使用消息首部的 Content-Length,对于静态资源,例如图片和静态页面,服务器可以很清楚的知道内容大小,然后通过 Content-length 消息首部字段告诉客户端 需要接收多少数据。客户端可以根据这个值来判断数据是否接收完成。
- 使用消息的首部 Transfer-Encoding,对于无法知道 Content-Length 的资源,例如:动态页面,服务器是不可能预先知道内容大小,这时就可以使用 Transfer-Encoding:chunk 模式来传输数据。服务器就需要使用 “Transfer-Encoding: chunked” 这样的方式来代替 Content-Length。Chunked 编码将使用若干个 Chunk 串连而成,由一个标明长度为 0 的 chunk 标示结束。
参考 https://blog.csdn.net/zhghost/article/details/112914408
https://blog.csdn.net/kingson_wu/article/details/72512825
https://blog.csdn.net/Kingson_Wu/article/details/80102077
强缓存 协商缓存#

Cache-Control
可缓存性
- no-cache 不使用强缓存
- no-store 不使用任何缓存
- private 响应只能被浏览器缓存,不能作为共享缓存(即代理服务器不能缓存它)
- public 都可以缓存
到期
- max-age: 例 max-age=10,相对于请求的时间 10 秒
Expires
值是一个绝对时间的 GMT 格式的时间字符串,例:expires
强缓存
强缓存 又分为 Disk Cache(存放在硬盘中)和 Memory Cache(存放在内存中),存放的位置是浏览器控制的。
Last-Modified 和 If-Modified-Since
请求一个资源,服务器返回 Last-Modified: (GMT 时间),再次请求时带上 If-Modified-Since: 值为 Last-Modified 返回的值。服务器根据 If-Modified-Since 的时间判断是否命中,命中返回 304。
ETag 和 If-None-Match
对不同资源生成不同的文件指纹。
协商缓存
在使用本地缓存之前,需要向服务器端发起一次 GET 请求,由服务器确定缓存资源是否可用(是否过期)。
跨源资源共享(CORS)#
内容安全策略(CSP)#
sessionStorage#
- 页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。
- 打开多个相同的 URL 的 Tabs 页面,会创建各自的 sessionStorage。
- 关闭对应浏览器标签或窗口,会清除对应的 sessionStorage。
用法
// 保存数据到 sessionStoragesessionStorage.setItem('key', 'value');
// 从 sessionStorage 获取数据let data = sessionStorage.getItem('key');
// 从 sessionStorage 删除保存的数据sessionStorage.removeItem('key');
// 从 sessionStorage 删除所有保存的数据sessionStorage.clear();300 重定向#
Location 指定一个重定向请求的目的地址
301 永久重定向
302 暂时重定向
扩展知识#
RTT#
RTT(Round-Trip Time):往返时延。是指数据从网络一端传到另一端所需的时间。通常,时延由发送时延、传播时延、排队时延、处理时延四个部分组成。
-
发送时延: 发送时延是结点将数据分组发送到传输媒介所需要的时间,也就是从分组的第一个比特开始发送算起,到最后一个比特发送完毕所需要的时间。显然,发送时延与网络接口/信道的传输速率成反比,与数据分组的长度成正比。
-
传播时延: 传播时延是电磁波在信道中传播一定距离所需要花费的时间,传播时延和信道的传输速率无关, 而是取决于传输媒介的长度,以及某种物理形式的信号在传输媒介中的传播速度。如电磁波在自由空间的传播速度是光速,即 3×105km/s。电磁波在网络传输媒体中的传播速度比在自由空间中的传播速度要略低一些,在铜线中的传播速度约为 2.3×105km/s,在光纤中的传播速度约为 2.0×105km/s 。
-
排队时延:排队时延是分组在所经过的网络结点的缓存队列中排队所经历的时延,排队时延的长短主要取决于网络中当时的通信量,当网络的通信流量大时,排队时间就长,极端情况下,当网络发生拥塞导致分组丢失时,该结点的排队时延视为无穷大。此外,在有优先级算法的网络中,排队时延还取决于数据的优先级和结点的队列调度算法。
-
处理时延:处理时延是分组在中间结点的存储转发过程中而进行的一些必要的处理所花费的时间,这些处理包括提取分组的首部,进行差错校验,为分组寻址和选路等。