网络相关知识(学自掘金小满zs)

计算机网络

osi七层模型

7.应用层

应用层就是我们使用最多的一层,例如ajax调用接口发送http请求,再比如域名系统DNS,邮件协议SMTP,webSocket长连接,SSH协议

6.表示层

表示层主要做了几件重要的事情 安全,压缩,也是程序在网络中的一个翻译官。
1.安全 在你的数据发送之前进行加密,在接受者的表示层进行解密。
2.表示层还会对图片文件等格式进行解码和编码 例如 JPEG、ASCll 图片是人类能读懂的计算机需要转换成计算机能读懂的编码。

5.会话层

会话层,是在发送方和接收方之间进行通信时创建、维持、之后终止或断开连接的地方,与电话通话有点相似。
会话层定义了一种机制,允许发送方和接收方启动或停止请求会话,以及当双方发生拥塞时仍然能保持对话。
会话层包含了一种称为检查点(Checkpoint) 的机制来维持可靠会话。检查点定义了一个最接近成功通信的点,并且定义了当发生内容丢失或损坏时需要回滚以便恢复丢失或损坏数据的点,即断点下载的原理

4.传输层

传输层主要就是定义我们的端口号,以及控流,和校验。
并且拥有两个熟知的协议 TCP UDP
TCP 是面向连接的协议并且TCP是可靠的
因为TCP会进行三次握手四次挥手所以是可靠的,但是这样会降低速度
UDP 具有较好的实时性 效率比TCP高
UDP是没有三次握手四次挥手的,故此不稳定,但是速度快 常用于直播,游戏

3.网络层

网络层是最复杂的一层,在这一层就定义了我们的IP,220.xxx.xxx.xxx。
该层控制数据链路层与传输层之间的信息转发,建立、维持和终止网络的连接。具体地说,数据链路层的数据在这一层被转换为数据包,然后通过路径选择、分段组合、顺序、进/出路由等控制,将信息从一个网络设备传送到另一个网络设备
1.寻址:对网络层而言使用IP地址来唯一标识互联网上的设备,网络层依靠IP地址进行相互通信(类似于数据链路层的MAC地址)
2.路由:在同一个网络中的内部通信并不需要网络层设备,仅仅靠数据链路层就可以完成相互通信,对于不同的网络之间相互通信则必须借助路由器等三层设备。
我们的路由器就是在第三层工作的
在数据链路层的时候说过了如果所有的使用互联网的用户在同一个网段中,会产生广播风暴,所以要将用户进行划分,让他们在不同的网段中,自己在自己的小网段中广播。而互联网就是这无数的子网络构成的一个巨型网络。
在网络层中引入了一套新的地址,让我们能够区分不同的网段。这套地址就叫做“网络地址”,简称“网址”。
于是,”网络层”出现以后,每台计算机有了两种地址,一种是MAC地址,另一种是网络地址。两种地址之间没有任何联系,MAC地址是绑定在网卡上的,网络地址则是管理员分配的,它们只是随机组合在一起。
网络地址帮助我们确定计算机所在的子网络,MAC地址则将数据包送到该子网络中的目标网卡。因此,从逻辑上可以推断,必定是先处理网络地址,然后再处理MAC地址。
这一层中有一个规定网络地址的协议,叫做IP协议,它所定义的地址,就被称为IP地址。目前,广泛采用的是IP协议第四版,简称IPv4。这个版本规定,网络地址由32个二进制位组成。因为IPv4的地址已经不够用了,所以现在推广IPv6,

2.数据链路层

建立逻辑连接、进行硬件地址寻址、差错校验等功能。(由底层网络定义协议)
将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。

MAC地址:每个网卡的唯一标识
有了Mac地址之后就可以知道谁是接收者,谁是发送者,并且知道了数据的内容并且进行了分组。

那么他如何进行传播数据,他是进行广播的方式进行传输,在局域网内所有的计算机都能收到消息

1.物理层

物理层是直接和物理介质打交道的。

物理层的设备 网卡,网线,集线器,中继器,调制解调器

物理层信道,有线信道,光纤,无线电波

TCP握手与挥手
浏览器输入url到按下回车发生了什么
强缓存,协商缓存
回流,重绘

回流:页面部分或者重新渲染
重绘:只需要更新相应内容,不会导致整个页面更新

CDN内容分发

寻求更近的资源服务器请求资源,减少请求延迟,提高用户体验。

跨域

jsonp,原理是script的src不受跨域访问限制,只能发送get,不安全,不容易维护,后端返回一个函数,前端定义一个函数,后端吧值注入到前端函数参数中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const jsonp = (name) => {
let script = document.createElement('script')
script.src = 'loacl..../jsonp?callback?=' + name
document.body.append(script)
return new Promise((resolve, reject)=>{
window[name] = (data) => {
resolve(data)
}
})

}

jsonp(`callback${new Date().getTime()}`).then(res => {
console.log(res)
})

前端代理
安装webpack和vite配置webpack.config.js和vite.config.js

后端解决
设置头,但是不安全

运维nginx

xhr,fetch(掘金小满zs)

application/x-www-form-urlencoded , 表单数据
multipart/form-data , 文件数据
fetch 的 API 设计更加现代化、简洁和易于使用,使用起来更加直观和方便。相比之下,XHR 的 API 设计比较繁琐,需要进行多个参数的配置和回调函数的处理。
fetch API 默认只支持 GET 和 POST 请求方法,而 XHR 则支持所有标准的 HTTP 请求方法。
在 fetch 中设置请求头部的方式更加清晰和直接,可以通过 Headers 对象进行设置,而 XHR 的方式相对较为繁琐。
在发送 POST 请求时,fetch API 要求将请求体数据作为参数传递给 fetch 方法中的 options 对象,而 XHR 可以直接在 send() 方法中设置请求体数据。
在解析响应数据时,fetch API 提供了多种方法,包括 .json(), .blob(), .arrayBuffer() 等,而 XHR 只支持文本和二进制数据两种数据类型。
在进行跨域请求时,fetch API 提供了一种简单而强大的解决方案——使用 CORS(跨域资源共享)头部实现跨域请求,而 XHR 则使用了一个叫做 XMLHttpRequest Level 2 的规范,在代码编写上相对较为繁琐。

fetch 返回格式

text(): 将响应体解析为纯文本字符串并返回。
json(): 将响应体解析为JSON格式并返回一个JavaScript对象。
blob(): 将响应体解析为二进制数据并返回一个Blob对象。
arrayBuffer(): 将响应体解析为二进制数据并返回一个ArrayBuffer对象。
formData(): 将响应体解析为FormData对象。

sse,websocket(掘金小满zs)

SSE(Server-Sent Events)是一种用于实现服务器主动向客户端推送数据的技术,也被称为“事件流”(Event Stream)。它基于 HTTP 协议,利用了其长连接特性,在客户端与服务器之间建立一条持久化连接,并通过这条连接实现服务器向客户端的实时数据推送

SSE 和 Socket 区别

SSE(Server-Sent Events)和 WebSocket 都是实现服务器向客户端实时推送数据的技术,但它们在某些方面还是有一定的区别。

技术实现

SSE 基于 HTTP 协议,利用了其长连接特性,通过浏览器向服务器发送一个 HTTP 请求,建立一条持久化的连接。而 WebSocket 则是通过特殊的升级协议(HTTP/1.1 Upgrade 或者 HTTP/2)建立新的 TCP 连接,与传统 HTTP 连接不同。

数据格式

SSE 可以传输文本和二进制格式的数据,但只支持单向数据流,即只能由服务器向客户端推送数据。WebSocket 支持双向数据流,客户端和服务器可以互相发送消息,并且没有消息大小限制。

连接状态

SSE 的连接状态仅有三种:已连接、连接中、已断开。连接状态是由浏览器自动维护的,客户端无法手动关闭或重新打开连接。而 WebSocket 连接的状态更灵活,可以手动打开、关闭、重连等。

兼容性

SSE 是标准的 Web API,可以在大部分现代浏览器和移动设备上使用。但如果需要兼容老版本的浏览器(如 IE6/7/8),则需要使用 polyfill 库进行兼容。而 WebSocket 在一些老版本 Android 手机上可能存在兼容性问题,需要使用一些特殊的 API 进行处理。

安全性

SSE 的实现比较简单,都是基于 HTTP 协议的,与普通的 Web 应用没有太大差异,因此风险相对较低。WebSocket 则需要通过额外的安全措施(如 SSL/TLS 加密)来确保数据传输的安全性,避免被窃听和篡改,否则可能会带来安全隐患。
总体来说,SSE 和 WebSocket 都有各自的优缺点,适用于不同的场景和需求。如果只需要服务器向客户端单向推送数据,并且应用在前端的浏览器环境中,则 SSE 是一个更加轻量级、易于实现和维护的选择。而如果需要双向传输数据、支持自定义协议、或者在更加复杂的网络环境中应用,则 WebSocket 可能更加适合。

1. EventSource() 构造函数
2. EventSource.readyState 属性
3. EventSource.close() 方法
4. EventSource.onopen 事件
5. EventSource.onerror 事件
6. EventSource.onmessage 事件

以上就是 EventSource 对象的常用 API 介绍,需要注意的是,在使用 EventSource 对象的过程中,如果服务器没有正确地设置响应头信息(如:Content-Type: text/event-stream),可能会导致 EventSource 对象无法接收到服务器发送的数据。

在 web 开发中,我们经常需要将用户行为或性能数据上报到服务器。为了不影响用户体验,开发者通常会在页面卸载时进行数据上报。然而,传统的数据上报方式,如 XMLHttpRequest 或 Fetch API,容易受到页面卸载过程中的阻塞,导致数据丢失。为了解决这个问题,navigator.sendBeacon API 被引入,它可以在页面卸载时安全、可靠地发送数据。

navigator.sendBeacon 对比 Ajax fetch
优点

不受页面卸载过程的影响,确保数据可靠发送。
异步执行,不阻塞页面关闭或跳转。
能够发送跨域请求。

缺点

fetch 和 ajax 都可以发送任意请求 而 sendBeacon 只能发送POST
fetch 和 ajax 可以传输任意字节数据 而 sendBeacon 只能传送少量数据(64KB 以内)
fetch 和 ajax 可以定义任意请求头 而 sendBeacon 无法自定义请求头
sendBeacon 只能传输 ArrayBuffer、ArrayBufferView、Blob、DOMString、FormData 或 URLSearchParams 类型的数据
如果处于危险的网络环境,或者开启了广告屏蔽插件 此请求将无效

navigator.sendBeacon 应用场景

发送心跳包:可以使用 navigator.sendBeacon 发送心跳包,以保持与服务器的长连接,避免因为长时间没有网络请求而导致连接被关闭。
埋点:可以使用 navigator.sendBeacon 在页面关闭或卸载时记录用户在线时间,pv uv,以及错误日志上报 按钮点击次数。
发送用户反馈:可以使用 navigator.sendBeacon 发送用户反馈信息,如用户意见、bug 报告等,以便进行产品优化和改进

其他注意事项 type
ping请求 是html5 新增的 并且是sendBeacon 特有的 ping 请求 只能携带少量数据,并且不需要等待服务端响应,因此非常适合做埋点统计,以及日志统计相关功能。

1
2
3
4
5
6
7
8
9
<button class="send">发送</button>
const send = document.querySelector('.send')
send.addEventListener('click', () => {
let data = JSON.stringify({name:'test'})
const blob = new Blob([data], { type: 'application/json' })
navigator.sendBeacon('http://localhost:3000/api/beacon',blob,{
type:"beacon"
})
})

nodejs

1
2
3
4
5
6
7
8
9
10
import express from 'express';
const app = express();
app.post('/api/beacon', (req: any, res) => {
console.log(req.body);
res.send('ok');
});

app.listen(3000, () => {
console.log('Listening on port 3000');
});