网络
网络通信模型(7层、4层和5层模型)
TCP三次握手和四次挥手
三次握手(Three-Way Handshake)是在建立TCP连接时使用的过程,具体步骤如下:
-
第一步(SYN):客户端向服务器发送一个带有SYN(同步)标志的TCP报文段,表示客户端请求建立连接。
-
第二步(SYN-ACK):服务器收到客户端的请求后,向客户端发送一个带有SYN和ACK(确认)标志的TCP报文段,表示服务器接受连接请求,并发送确认。
-
第三步(ACK):客户端收到服务器的确认后,向服务器发送一个带有ACK标志的TCP报文段,表示客户端确认连接已建立。
四次挥手(Four-Way Handshake)是在终止TCP连接时使用的过程,具体步骤如下:
-
第一步(FIN):当客户端想要关闭连接时,发送一个带有FIN(结束)标志的TCP报文段给服务器,表示客户端不再发送数据。
-
第二步(ACK):服务器收到客户端的结束请求后,发送一个带有ACK标志的TCP报文段给客户端,表示服务器收到了结束请求。
-
第三步(FIN):当服务器也想要关闭连接时,发送一个带有FIN标志的TCP报文段给客户端,表示服务器不再发送数据。
-
第四步(ACK):客户端收到服务器的结束请求后,发送一个带有ACK标志的TCP报文段给服务器,表示客户端收到了结束请求。
少一次可以吗
- TCP 的连接需要三次握手,三次握手可以保证可靠性并且避免浪费资源。
- TCP 的断开需要四次挥手,四次挥手可以保证全双工通信彻底断开。
TCP和UDP的区别
TCP和UDP是传输层两大核心协议。 TCP通过连接管理、重传机制等保证可靠(序列号和应答号机制保证可靠)传输,适合网页加载、文件下载等场景; UDP无连接、速度快但不可靠,适合实时音视频或在线游戏。
场景举例:
- TCP:HTTP请求、WebSocket长连接、SSH远程登录。
- UDP:WebRTC实时音视频(容忍丢帧、降低延迟)、在线游戏状态同步、QUIC协议(HTTP/3底层)。
长轮询与短轮询
短轮询:
客户端每隔一段时间向服务器发送http请求,服务器端在收到请求后,无论是否有数据更新,都直接进行响应。
长轮询:
客户端发送请求后不会立即返回数据,服务器端会阻塞请求,连接不会立即断开,直到服务器端有效更新或者是连接超时才返回,客户端才再次发出请求新建连接、如此反复从而获得最新数据。
WebSocket
-
WebSocket 是一种基于 TCP 的网络协议,支持客户端与服务器之间的全双工实时通信。它打破了传统 HTTP 请求-响应模式的限制,为实时交互场景提供了高效解决方案。
-
过程:
- 建立连接: WebSocket 协议属于应用层协议,依赖传输层的 TCP 协议。它通过 HTTP/1.1 协议的 101 状态码进行握手建立连接。
- 客户端发送一个 HTTP GET 请求到服务器,请求的路径是 WebSocket 的路径(类似 ws://example.com/socket)。请求中包含一些特殊的头字段,如 Upgrade: websocket 和 Connection: Upgrade,以表明客户端希望升级连接为 WebSocket。
- 服务器收到这个请求后,会返回一个 HTTP 101 状态码(协议切换协议)。同样在响应头中包含 Upgrade: websocket 和 Connection: Upgrade,以及一些其他的 WebSocket 特定的头字段,例如 Sec-WebSocket-Accept,用于验证握手的合法性。
- 客户端和服务器之间的连接从普通的 HTTP 连接升级为 WebSocket 连接。之后,客户端和服务器之间的通信就变成了 WebSocket 帧的传输,而不再是普通的 HTTP 请求和响应
- 数据通信:WebSocket 的每条消息可能会被切分成多个数据帧(最小单位)。发送端会将消息切割成多个帧发送给接收端,接收端接收消息帧并将关联的帧重新组装成完整的消息。
- 维持连接:当建立连接后,连接可能因为网络等原因断开,我们可以使用心跳的方式定时检测连接状态。若连接断开,我们可以告警或者重新建立连接。
- 关闭连接:WebSocket 是全双工通信,当客户端发送关闭请求时,服务端不一定立即响应,而是等服务端也同意关闭时再进行异步响应
- 事件
- onopen
- onmessage
- onerror
- onclose
- 心跳机制
- 定时发数据
- 断线重连
- 应用场景
- 即时通讯(如聊天室、通知系统)
- 实时数据推送(股票行情、体育赛事比分)
- 协同编辑工具(多用户实时同步文档)
- 在线游戏(玩家状态实时同步)
- IoT 仪表盘(设备数据实时监控)
操作系统
线程与进程
- 进程(Process) :操作系统分配资源的最小单位,拥有独立的内存空间。
- 线程(Thread) :CPU调度的最小单位,共享进程内的资源。
前端角度下:
- 浏览器
- Browser进程:管理其他进程
- Renderer进程:每个标签页对应一个进程,负责页面渲染、JS执行
- GPU进程:加速图形渲染。
- 插件进程:隔离第三方插件。
- 渲染线程:计算样式、布局、绘制、合成等
- js
- js单线程
- Web Worker:允许在浏览器中创建子线程,复杂计算
- Service Worker:
- 独立于页面生命周期,可拦截网络请求。
- 支持离线缓存(Cache API)、消息推送(Push API)
安全
同源策略的安全限制
安全限制主要分三个方面:
- DOM层面:同源策略限制了不同源的js对当前DOM对象的读写操作
- 数据层面:同源策略限制了不同源站点读取当前站点的Cookies、IndexDB、LocalStorage等数据
- 网络层面:同源策略限制了数据发送给非同源站点(比如XML HttpRequest、Fetch等无法请求不同源站点)
预检请求
- 定义:预检请求(Preflight Request) 是浏览器在发送某些跨域请求(CORS,跨源资源共享)之前,自动发起的一个OPTIONS请求。它的目的是确认服务器是否允许实际的跨域请求,从而避免潜在的安全风险
- 哪些情况会触发预检请求
- 使用非简单请求方法(如
PUT
、DELETE
、PATCH
等,简单方法仅限GET
、POST
、HEAD
)。 - 包含自定义请求头(如
Authorization
、X-Custom-Header
)。 Content-Type
不是简单值(如application/json
,而简单值包括text/plain
、multipart/form-data
、application/x-www-form-urlencoded
)。
- 使用非简单请求方法(如
- 合理利用
Access-Control-Max-Age
可减少预检请求次数,提升性能
解决跨域方案
- 通过jsonp跨域
- document.domain + iframe跨域(主子跨站)
- location.hash + iframe(a欲与b跨域相互通信,通过与a同域的中间页c来实现)
- window.name + iframe跨域(window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB))
- postMessage(data,origin)跨域
- 跨域资源共享(CORS)
response.setHeader("Access-Control-Allow-Origin", "www.domain1.com"); 7. nginx代理跨域
perl
server {
listen 80;
server_name your-domain.com;
location / {
# 允许所有来源的跨域请求(生产环境建议限制为具体域名)
add_header 'Access-Control-Allow-Origin' '*';
# 允许的请求方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
# 允许的请求头
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
# 预检请求缓存时间(单位:秒)
add_header 'Access-Control-Max-Age' 1728000;
# 允许携带凭证(如 Cookie、Authorization)
add_header 'Access-Control-Allow-Credentials' 'true';
# 处理 OPTIONS 预检请求
if ($request_method = 'OPTIONS') {
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain; charset=utf-8';
return 204;
}
# 其他代理配置(如反向代理到后端服务)
proxy_pass http://backend-server;
}
}
- webpack、vite代理跨域 9. WebSocket协议跨域
在握手阶段,浏览器会向服务器发送一个特殊的HTTP请求,这个请求包含了Origin
头,用于告知服务器请求的来源。如果服务器响应中包含一个允许跨域的Access-Control-Allow-Origin
头,那么WebSocket连接就可以建立