Skip to content

Commit d802d84

Browse files
张东张东
张东
authored and
张东
committed
add
1 parent 35d8755 commit d802d84

File tree

6 files changed

+191
-5
lines changed

6 files changed

+191
-5
lines changed

.vitepress/config.mts

+13
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export default defineConfig({
8686
items: [
8787
{ text: "about", link: "/browser/about/overview" },
8888
{ text: "dev-tool", link: "/browser/devtool/source" },
89+
{ text: "http", link: "/browser/http/introduct" },
8990
],
9091
},
9192
{ text: "性能优化", link: "/optimization/image" },
@@ -118,6 +119,10 @@ export default defineConfig({
118119
text: "虚拟列表",
119120
link: "/javascript/application/virtualList",
120121
},
122+
{
123+
text: "文件切片上传",
124+
link: "/javascript/application/fileSlice",
125+
},
121126
],
122127
},
123128
],
@@ -270,6 +275,14 @@ export default defineConfig({
270275
],
271276
},
272277
],
278+
"/browser/http/": [
279+
{
280+
text: "http",
281+
items: [
282+
{ text: "概述", link: "/browser/http/introduct" },
283+
],
284+
},
285+
],
273286
"/browser/devtool/": [
274287
{
275288
text: "devtool",

browser/http/introduct.md

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
layout: doc
3+
outline: deep
4+
---
5+
应用层协议,http是无状态协议,意味着服务器不会在两个请求之间保存任何数据
6+
7+
发送多个http请求是串行的
8+
9+
## http无状态但是并非无会话
10+
借助http cookie可以共享相同的上下文
11+
12+
## cookie带来的安全问题
13+
标记为secure的cookie只会通过https加密后的请求发送给服务端,可以防止中间人攻击,但是无法阻止js api拿到cookie
14+
15+
标记为httpnoly将阻止js api拿到cookie,缓解xss攻击
16+
## http 发展
17+
18+
### http1.1的提升
19+
1. tcp连接可以复用
20+
2. 通过host标头,不同域名可以配置在同一个ip地址的服务器上
21+
3. 引入额外的缓存控制机制
22+
4. 增加管线化技术,请求发送成功之后即可发送下一个,不必等待上一个请求的响应,但是支持不佳和复杂性很少使用
23+
### http2.0的提升
24+
1. 二进制协议,非文本协议,无法手动读取和创建
25+
2. 多路复用,可以通过同一个连接发送并发请求。解决流水线模式的队头阻塞问题
26+
3. 压缩请求头(数据帧和报头帧分离,这将允许报头压缩)。由于请求头在一组请求里通常很相似,减少了数据传输的消耗
27+
28+
HTTP2允许在单个tcp内处理多个请求和响应,这是通过将信息包装成二进制帧,并在连接上以编号流的形式发送请求和响应来实现的
29+
30+
帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。
31+
32+
多路复用,就是在一个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,可以通过帧中的标识知道属于哪个请求
33+
<img src="https://mdn.github.io/shared-assets/images/diagrams/http/messages/http-2-connection.png" alt="使用单个 TCP 连接在 HTTP/2 中多路复用请求和响应。" loading="lazy">
34+
请求不一定连续,例如流9不需要流7结束,来自多个流的数据通常在连接上交错
35+
36+
也可以为每个流或者资源设置优先级,低优先级的带宽比高优先级少
37+
38+
由于每个帧都有一个与之关联的流 ID,因此客户端和服务器无需按顺序处理 HTTP 请求和响应。因此,HOL 阻塞问题在 HTTP 层得到解决,但现在转移到了 TCP 层。
39+
## HTTP/1.x中的连接管理
40+
有几种模型:短期连接、持久连接和HTTP 流水线
41+
42+
后面两种是1.1新引入的
43+
<img src="https://developer.mozilla.org/en-US/docs/Web/HTTP/…on_management_in_HTTP_1.x/http1_x_connections.png" alt="比较三种 HTTP/1.x 连接模型的性能:短暂连接、持久连接和 HTTP 流水线。" width="1012" height="670" loading="lazy">
44+
45+
### 短暂连接(1.0默认模型)
46+
HTTP/1.0 默认为每一对 HTTP 请求/响应都打开一个单独的 TCP 连接,通过设置connection除了close之外任何值会变成持久化
47+
### 持久连接(1.1默认模型)
48+
tcp连接可以给不同请求复用
49+
在 HTTP/1.1 中,不再需要标头(但它通常被添加作为针对需要回退到 HTTP/1.0 的情况的防御措施)。
50+
### http流水线
51+
默认情况下,HTTP请求是按顺序发出的。只有在收到当前请求的响应后才会发出下一个请求。由于它们受到网络延迟和带宽限制的影响,这可能会导致服务器在看到下一个请求之前有显著的延迟。
52+
53+
1. 流水线要求客户端只有在前一个请求成功发送后才开始发送后续请求。但这些请求可以不等待其响应就发送。
54+
2. 它还要求服务器按照收到请求的顺序发送响应。
55+
3. 客户端收到的响应也需要按顺序进行处理。
56+
57+
这意味着客户端和服务器始终需要使用流水线按顺序处理请求和响应。
58+
59+
这种请求和响应的排序是必须的,否则客户端和服务器就无法确定相应的请求和响应。所以会产生队头阻塞
60+
61+
这也使得流水线的实现存在缺陷且容易出错,尤其是在中间有代理的情况下,因此几乎所有 浏览器都默认禁用流水线。
62+
## 请求/响应结构
63+
<img src="https://mdn.github.io/shared-assets/images/diagrams/http/messages/http-message-anatomy.svg"/>
64+
请求和响应都具有相似的结构:
65+
66+
1. 起始行(请求行)是一行,描述 HTTP 版本以及请求方法或请求结果。由`<method> <request-target> <protocol>`组成
67+
2. 一组可选的HTTP 标头,其中包含描述消息的元数据。例如,对资源的请求可能包含该资源允许的格式,而响应可能包含标头以指示返回的实际格式。
68+
3. 空行,表明消息的​​元数据已完成。
69+
4. 可选主体,包含与消息相关的数据。这可能是在请求中发送到服务器的 POST 数据,也可能是在响应中返回给客户端的某些资源。消息是否包含主体由起始行和 HTTP 标头决定。
70+
71+
HTTP 消息的起始行和报头统称为请求的头,之后包含其内容的部分称为正文。
72+
73+
## 一个tcp里请求串行发送?(与协议有关)
74+
在 HTTP/1.1 中,如果您想并行发出两个请求(单个tcp上请求是依次发送的),则必须打开两个tcp连接:
75+
76+
<img src="https://mdn.github.io/shared-assets/images/diagrams/http/messages/http-1-connection.png" alt="并行向服务器发出两个 HTTP 请求" loading="lazy">
77+
78+
这意味着浏览器可以同时下载和渲染的资源数量受到限制,通常限制为 6 个并行(tcp)连接。
79+
80+
但是对于http2,请求是并行发送的
81+
## 参考
82+
[HTTP/1 和 HTTP/2 中的队头 (HOL) 阻塞](https://engineering.cred.club/head-of-line-hol-blocking-in-http-1-and-http-2-50b24e9e3372)

commitlint.config.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ module.exports = defineConfig({
7575
aiNumber: 1,
7676
themeColorCode: "",
7777
scopes: [
78-
{ value: "app", name: "app: 系统业务" },
79-
{ value: "home", name: "home: 首页相关" },
80-
{ value: "account", name: "account: 账户相关" },
81-
// { value: "comment", name: "comment: 评论相关" },
78+
// { value: "app", name: "app: 系统业务" },
79+
// { value: "home", name: "home: 首页相关" },
80+
// { value: "account", name: "account: 账户相关" },
81+
// { value: "comment", name: "comment: 评论相关" },
8282
],
8383
allowCustomScopes: false,
8484
allowEmptyScopes: false,

javascript/application/fileSlice.md

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
outline: deep
3+
---
4+
首先对文件进行切片,传入一个file对象,file对象继承了blob(/blab/)的slice(/slais/)方法,使用它对文件按指定大小进行切割获得blob切片数组。
5+
```js
6+
const createFileChunk = (file: UploadRawFile, size = CHUNKSIZE) => {
7+
const fileChunkList = []
8+
let cur = 0
9+
while (cur < file.size) {
10+
fileChunkList.push({
11+
file: file.slice(cur, cur + size)
12+
})
13+
cur += size
14+
}
15+
return fileChunkList
16+
}
17+
```
18+
针对文件生成唯一标识,使用spark-md5(/spa:rk/)生成hash。考虑到这一步将占用大量资源,阻塞主线程。因此在web worker中进行这个操作
19+
20+
调用初始化上传接口,请求参数是切片数,文件hash。返回taskId
21+
22+
调用切片上传接口,入参切片序号,taskId,请求体里文件切片(formData),返回成功,更新上传进度
23+
24+
但是浏览器限制并发请求的个数,如果使用promise.all一次性的并发请求太多可能导致请求直接失败,使用p-limit帮助我们解决限制并发个数的问题
25+
26+
优化:
27+
28+
秒传,在初始化上传接口中如果后端根据hash发现文件已经存在,则会返回一个特殊的状态码表示该文件已存在
29+
30+
断点上传,调用初始化上传接口,如果没有上传完,返回缺失的切片序号,前端再补充上传缺失的切片即可
31+
32+
暂停上传,axios提供的AbortController取消上传
33+
34+
```
35+
const controller = new AbortController();
36+
37+
axios.get('/foo/bar', {
38+
signal: controller.signal
39+
}).then(function(response) {
40+
//...
41+
});
42+
// 取消请求
43+
controller.abort()
44+
```
45+
46+
恢复上传,已知已上传成功列表,只需要上传除此之外的切片

vscode/develop.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
layout: doc
3+
outline: deep
4+
---
5+
## 启动,调试
6+
1. F5会进行插件打包,本质webpack watch不断监听修改并重新打包,如果修改配置需要reload window
7+
2. 代码里debugger即可
8+
## 发布
9+
`vsce publish`即可,或者`vsce package`本地打包,[地址](https://marketplace.visualstudio.com/manage/publishers/dddssw)进行查看
10+
11+
修改readme文件,即可在vscode插件市场里展示

vscode/extension.md

+35-1
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,38 @@ vscode.workspace.getConfiguration('jsonOutline').get('autorefresh', false);
8383
```js
8484
vscode.window.activeTextEditor.document.uri.scheme === 'file'//区分本地还是远程文件
8585
vscode.window.activeTextEditor.document.languageId === 'json'//语言标识符
86-
```
86+
```
87+
88+
## 注册命令
89+
使用 registerCommand 进行注册,并且在package.json进行注册
90+
```js
91+
//package.json
92+
"contributes": {
93+
"commands": [
94+
{
95+
"command": "speed-up.element-plus",
96+
"title": "insert element-plus"
97+
}
98+
]
99+
}
100+
```
101+
在命令面板搜 title:`insert element-plus`,而不是`speed-up.element-plus`
102+
103+
104+
# 插件speed up (zustand 全局状态管理)
105+
## 功能1
106+
生成element-plus模板,需要结合脚手架
107+
### 使用
108+
1. 集成终端搜索`active element-plus termine`,在这个终端下进行脚手架命令,执行脚手架(snippetvue)交互(命令名:gen el),等待代码生成
109+
2. 文件编辑器鼠标右键有一个`插入element-plus组件模板`,点击就会在光标的位置进行插入
110+
111+
### 思路
112+
1. vscode创建终端,注意是集成终端,在终端执行脚手架命令,执行完毕,在onDidEndTerminalShellExecution可以监听到,但是他们之间通信不了
113+
2. 所以脚手架执行完之后将数据保存在一个文件,onDidEndTerminalShellExecution监听脚手架命令执行完毕再读取这个文件拿到数据
114+
3. 拿到数据存在全局,在当前编辑文件右击多出一个 `插入element-plus组件模板` 的命令
115+
116+
# 脚手架snippetvue
117+
## 功能1
118+
`gen el`
119+
120+
生成element plus组件代码模板

0 commit comments

Comments
 (0)