网络
coderljw 2024-10-13 大约 7 分钟
# 1. TCP
TCP 是一个面向连接的、可靠的、基于字节流的传输层协议。
三次握手:握手需要三次是为了确认双方的发送能力和接收能力。
四次挥手:挥手四次是须等待服务端所有数据发送完成,确认双方都已做好断开连接的准备。
# 2. HTTP、HTTPS、HTTP/2
- 常见状态码。
Code | 常见原因 |
---|---|
200 | 请求成功 |
204 | 无实体内容(Body) |
206 | 分块下载、断点续传(必须包含 Content-Range) |
301 | 永久重定向(浏览器默认会做缓存优化) |
302 | 临时重定向(只有在 Cache-Control 或 Expires 中进行了指定的情况下,这个响应才是可缓存的) |
304 | 命中协商缓存 |
307 | 302 升级版(可以确保请求方法和消息主体不会发生变化) |
308 | 301 升级版(可以确保请求方法和消息主体不会发生变化) |
400 | 可能是请求参数有误 |
401 | 身份验证失败(无权限) |
403 | 禁止访问 |
404 | 资源未找到 |
405 | 请求方法错误 |
500 | 服务器错误 |
502 | 网关错误 |
503 | 服务器繁忙 |
504 | 网关超时 |
- HTTP
特点 | 概括 |
---|---|
无状态 | 每一次请求都是独立的,请求结束不会记录连接的任何信息,同时也减少了网络开销 。 |
明文传输 | 报文(主要指头部)使用文本形式的数据,利用路由器等中转设备,可从中获取数据、串改数据。 |
串行连接 | HTTP 有无连接的特性,即每次连接只能处理一个请求,收到响应后立即断开连接。 |
持久连接 | 同一域名下的 HTTP 请求,只要两端都没有提出断开连接,则持久保持 TCP 连接状态,其他请求可以复用这个连接通道(HTTP/1.1 默认是持久连接)。持久连接采用阻塞模式:下次请求必须等到上次响应返回后才能发起,也就是著名的队头阻塞。 |
管道化持久连接 | 管道化则可以不用等待响应返回而发送下个请求并按顺序返回响应,目前没有现代浏览器默认启用这个特性。依然存在队头阻塞问题。 |
并发连接 | 对于一个域名允许分配多个长连接,那么相当于增加了任务队列,不至于一个队伍的任务阻塞其它所有任务。比较常用的并发连接数已经增加到 6 条,如果尝试大于这个数字,就有触发服务器 DoS 保护的风险。可以使用域名分片技术,建立更多的连接。HTTP/2 拥有多路复用特点,不需要依赖 TCP 连接实现多流并行了,在 HTTP/2 中同域名下的通信都在单个连接上完成。 |
头部压缩(HTTP/2) | 使用 HPACK 算法对请求头进行压缩,在服务器与客户端建立头部字段哈希表,以及对整数和字符串使用哈夫曼编码(废除了起始行的概念,转换为头部字段)。 |
多路复用(HTTP/2) | HTTP/2 将报文换成二进制格式,Headers 帧存放头部字段,Data 帧存放请求体数据。分帧后就不是一个个完整的 HTTP 请求报文了,而是一堆乱序的二进制帧,二进制帧不存在先后关系,也就不存在队头阻塞的问题了。这种二进制帧的双向传输的序列,也叫做流(Stream)。多路复用就是在一个 TCP 连接中可以存在多条流,即可以发送多个请求,服务端通过帧中的 Stream ID 重新排序还原请求。 |
- HTTPS 特点:密文传输、报文完整性保护、第三方机构身份认证,同时也增加了网络开销。
提示
主流的浏览器都公开只支持加密的 HTTP/2
# 3. CORS
浏览器向服务器发送请求,会自动加上 origin 请求头,如果响应头中 Access-Control-Allow-Origin 不为 * 或不为 origin 字段指明的域名,浏览器就会拦截响应数据,报出跨域错误。
CORS 是跨域 AJAX 请求的根本解决方法,实现 CORS 通信的关键是服务器,只要服务器实现了 CORS 接口,就可以跨域通信。
CORS 请求分为两类:简单请求和非简单请求。
- 简单请求:当请求是 GET、HEAD、POST 方法并且没有任何自定义 Header 字段时,一般来说就是个简单请求(简单请求 - MDN (opens new window))。
- 非简单请求(需预检请求):除上述简单请求外均为非简单请求。须先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。预检请求可以避免跨域请求对服务器的用户数据产生未预期的影响。
跨域请求携带 Cookie 条件:
- xhr.withCredentials 为 true 或 fetch 配置 credentials 为 include
- 网站开启 https 并将 Cookie 的 Secure 属性设置为 true
- Cookie 的 SameSite 属性设置为 None
- 响应头 Access-Control-Allow-Origin 设置为具体的 origin,不能设置为 *
- 响应头 Access-Control-Allow-Credentials 设置为 true
# 4. JSONP
JSONP 利用了 script 标签不会进行同源检测的特点。
前端定义一个回调函数,形参为要接收的数据,将回调函数名称通过 URL 查询参数的 callback 字段(前后端业内默认约定,也可约定其他字段)传递到后端。
https://www.coderljw.ga/?callback=foo
(前端回调函数名称为foo
)后端接收到 callback 字段的值后,将数据通过实参传入函数,返回前端定义的回调函数执行文本。浏览器解析到 JSONP 的 script 标签,就会执行这个回调函数,从而获取到数据。
send(`foo(${JSON.stringify(Matrix)})`)
(后端返回函数foo(Matrix)
执行脚本,script 标签解析执行后,前端获得Matrix
)
注意
JSONP 的 script 标签要在用户定义回调函数的 script 标签下方 --> 默认的 script 标签依次加载
# 5. Cookie、Session、Token、JWT
- HTTP 是无状态的,Cookie、Session、Token、JWT(JSON Web Token)可以维持前后端会话状态。
方式 | 特点 |
---|---|
Cookie | 1. 存储在客户端(限 4k),向服务器发送请求时会自动携带 2. 限 Web 项目使用、默认不可跨域、小心 XSS/CSRF 攻击 3. 可通过设置 withCredential/credentials 跨域请求携带 Cookie 4. 设置 HttpOnly/SameSite 可防止 XSS/CSRF 攻击 |
Session | 1. 基于 Cookie 实现,Session 存储在服务器端,SessionId 会被存储到客户端的 Cookie 中 2. 须查询数据库、占用服务器资源、要考虑分布式问题 |
Token | 1. 简单组成:uid.time.sign(ID.失效时间.签名) 2. 服务器端无状态化,支持 Web、APP 等项目,安全性较高 3. 须查询数据库 |
JWT | 1. 一种基于 Token 的开放标准 2. 组成:Header.Payload.Signature(头部.负载.签名) 3. 将用户信息存储于 Payload,不必查询数据库 |