
为什么 get 请求有长度的限制
大多数 Web 服务器的限制为 8192 字节 (8 KB)。协议并不限制 HTTP Get 请求的长度,但不同的浏览器会进行限制。
http 请求有那些字段
请求
- If-Modified-Since:用于协商缓存,If-Modified-Since 的 value 是之前响应头上的 Last-Modified 的 value,服务器资源的最后的修改时间。
- If-None-Match:用于协商缓存,value 是之前响应头上的 ETag 的 value 返回给服务端,判断文件是否发生了变化
- Cache-Control:用于强缓存, 如果 value 是 no-cache 告知代理服务器不直接使用缓存,要求向原服务器发起请求。如果 value 是 no-store 不使用缓存,每次永远都要从原始服务器获取资源。
- Content-Type:内容类型
- Content-Length:文件的大小
- Host:请求将要发送到的服务器主机名和端口号
- Origin:请求来自于哪个站点。该字段仅指示服务器名称,并不包含任何路径信息 协议+域名+端口号
- Referer:当前请求页面的来源页面的地址
- User-Agent:会告诉网站服务器,访问者是通过什么工具来请求的
- Connection:是否是长连接
响应
- Last-Modified:用于协商缓存,返回资源最后的修改时间
- ETag:用于协商缓存,ETag 是资源的唯一标识(由服务器生成)
- Expires:用于强缓存
- Cache-Control:用于强缓存
- Content-Encoding:用于对特定媒体类型的数据进行压缩
Cache-Control 对比 Expires
- Cache-Control 是 HTTP1.1 新增。Expires是 HTTP1
- Cache-Control 的优先级要大于 Expires,如果包含 Cache-Control 带有 max-age 会忽略 Expires
- Cache-Control 和 Expires 设置的值不一样
- expires: 1d; 一天后过期
- cache-control: max-age=3600; 最大缓存时间3600秒
If-Modified-Since 和 Last-Modified 对比 If-None-Match 和 ETag
- ETag 对于客户端是不透明的,Last-Modified 对于客户端是透明的
- ETag 更消耗性能
- 如果服务器的资源,1s 内修改了两次,If-Modified-Since 会失效
WebSocket使用的是 TCP 还是 UDP 协议
基于 TCP 协议
post 和 get 的区别
- post 的参数是在 body 中,get 的参数在 url 中
- post 不能被缓存,get 请求会被缓存
- get 不应用于会导致副作用的操作,具有幂等性。post 请求用来处理数据。
- get 请求 url 有长度限制。post 没有限制。
- post 要比 get 安全。
- get 的参数只能支持 ASCII 字符集,post 支持任意编码。
正向代理
正向代理,正向代理是客户端和其他所有服务器(重点:所有)之间的代理者。比如 VPN,所有可以连接到该代理服务器的软件,就可以通过代理访问任何的其他服务器,然后把数据返回给客户端,这里代理服务器只对客户端负责, 这是正向代理。
反向代理
反向代理,反向代理是客户端和所要代理的服务器之间的代理。如果反向代理了两个服务,那么之后客户端访问这两个服务器的时候,该代理服务器才会给它代理,也就是说,这里的代理服务器只对该代理服务器所代理的服务器负责。这是反向代理。
http 状态码
- 301 (永久重定向) 请求的网页已永久移动到新地址。服务器返回此响应,浏览器会自动将请求者转到新地址。
- 302 (临时重定向) 旧地址仍然可以访问。比如未登录时,会跳转到登录页。
- 304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。数据从缓存获取。
- 400 (错误请求) 服务器不理解请求的语法。
- 401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
- 403 (禁止) 服务器拒绝请求。
- 404 (未找到) 服务器找不到请求的资源。
- 405 (方法禁用) 禁用请求中指定的方法。
- 500 (服务器内部错误) 服务器遇到错误,无法完成请求。
- 501 (尚未实施) 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。
- 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
- 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。
- 504(网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
- 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
301与302的区别
对于 301 请求,浏览器是默认给一个很长的缓存。而 302 是不缓存的。
旧地址 A 的资源不可访问了(永久移除), 重定向到网址 B,搜索引擎会抓取网址 B 的内容,同时将网址保存为 B 网址。而302是资源仍然可以访问,只是重定向临时从地址 A 转到了 B,此时搜索引擎会抓 B 的内容,但是网址还是 A 的,所以不利于 SEO。
301 和 302 对 SEO 有什么影响
- 301 重定促进搜索引擎优化效果
- 302 重定影响搜索引擎优化效果
http 常用的请求方式
- GET
- POST
- PUT
- DELETE
- HEAD,HEAD几乎与GET相同,但没有响应正文
- OPTIONS
同源策略和跨域解决方案
协议/域名/端口,三者有一个不同就是跨域。二级域名之间也存在跨域问题。
对于不同源有如下的限制:
- cookie、localStorage 和 indexDB 无法读取
- ajax请求不能发送,提示安全问题
跨域解决方案
- cors
- jsonp
- nginx转发
- node中间层
JSONP原理
JSONP, 利用 script 标签不会跨域实现了跨域请求。JSONP 只支持 GET 请求。
js
// 首先需要在全局实现 handleResponse 函数
function handleResponse(response) {
console.log(` You're at IP address ${response.ip}, which is in ${response.city}, ${response.region_name}`
);
}
// 发起 jsonp 请求, 在 html 中插入 script 标签
let script = document.createElement("script");
script.src = "http://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);
// 通常 script 标签会加载如下的内容, 这样就会调用全局下的 handleResponse函数
// handleResponse('我是数据')
CORS
CORS 会将请求分为简单请求和非简单请求。
如果请求方法是,HEAD,GET,POST,三种之一。并且头信息不超过 Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type 就是简单请求。
简单请求
对于简单请求,浏览器直接发出 CORS 请求。具体来说,就是在头信息之中,增加一个 origin 字段。origin 字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
如果 origin 指定的源,不在许可范围内,会返回错误。如果 origin 指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段:
- Access-Control-Allow-Origin:该字段是必须的。它的值要么是请求时 Origin 字段的值,要么是一个*,表示接受任意域名的请求。
- Access-Control-Allow-Credentials:该字段可选。它的值是一个布尔值,表示是否允许发送 Cookie。(ajax 要设置 withCredentials 属性,但是此时Access-Control-Allow-Origin 不能设置为星号。
- Access-Control-Expose-Headers:该字段可选。CORS 请求时,XMLHttpRequest 对象的 getResponseHeader() 方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在 Access-Control-Expose-Headers 里面指定。
非简单请求
非简单请求的 CORS 请求,会在正式通信之前,增加一次 HTTP 查询请求,称为"预检"请求(preflight)。"预检"请求用的请求方法是 OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是 Origin,表示请求来自哪个源。除了 Origin 字段,"预检"请求的头信息包括两个特殊字段:
- Access-Control-Request-Method:正式请求时用到的方法
- Access-Control-Request-Headers:该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段。
HSTS
HSTS(HTTP Strict Transport Security), 强制客户端使用 HTTPS 访问页面,使用原理:
- 在服务器响应头中添加 Strict-Transport-Security,可以设置 max-age
- 下次如果使用 http 访问,如果 max-age 未过期,客户端会进行内部跳转,可以看到 307 Redirect Internel 的响应码
- 客户端之后会使用 https 访问页面
缓存
缓存命中规则

先检查是否命中强缓存,如果没有命中,检查是否命中协商缓存
强缓存
强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。强缓存又分为两种 Expires 和 Cache-Control
Expires
HTTP/1.0, 存在在HTTP返回的响应头之中
shell
# 一天后过期
expires 1d;
Cache-Control
HTTP/1.1, 存在在 HTTP 响应头以及请求头之中。
shell
# 最大缓存时间3600秒
Cache-Control:max-age=3600
cache-control: no-cache 与 cache-control: no-store 的区别
- no-store: 永远都不要在客户端存储缓存,每次永远都要从原始服务器获取资源。
- no-cache:
- 如果在请求头之中。告知代理服务器不直接使用缓存,要求向原服务器发起请求。
- 如果在响应头之中。表示可以在客户端存储资源,但每次都「必须去服务器做新鲜度校验」,来决定从服务器获取最新资源 (200) 还是从客户端读取缓存 (304),即所谓的协商缓存。
协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
Last-Modified / If-Modified-Since
- Last-Modified, 位于响应头上,浏览器在第一次发送请求后,服务器响应会携带上 Last-Modified 字段,返回给客户端, Last-Modified 的 value 是资源最后的修改时间。
- If-Modified-Since, 位于请求头上,浏览器在下一次请求的时候,会把之前 Last-Modified 字段的携带上,服务器获取 If-Modified-Since 字段后,会和服务器中该资源的最后修改时间 Last-Modified 对比, 询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来。否则读取本地缓存。
ETag / If-None-Match
ETag 会额外的消耗服务器资源
- ETag,位于响应头上,ETag 是资源的唯一标识,由服务器生成,会在返会响应的时候,将这个值给浏览器
- If-None-Match,位于请求头上,浏览器再次请求的时候,会将 ETag 的值通过 If-None-Match 字段发送给服务器。当服务器发现 If-None-Match 的值与资源的标识一致时,则返回 304,并从本地缓存获取资源,否则重新获取新数据。
DNS
DNS,域名解析系统,是因特网上作为域名和 IP 地址相互映射的一个分布式数据库。它的作用非常简单,就是可以根据域名查出对应的 IP 地址。DNS 查询分为递归查询和迭代查询。优先递归查询,然后是迭代查询。
DNS 解析的过程
- 首先,会依次检查浏览器缓存,操作系统缓存,本地硬盘的 hosts 文件,路由器缓存,查找对应的 IP 地址,找到就直接返回;否则下一步。
- 将请求发送给本地DNS服务器,在本地 DNS 服务器缓存中查询,如果查找到就直接返回,否则下一步;(1, 2都是递归查询,这些缓存被称为DNS高速缓存)
- 本地 DNS 服务器向根域名服务器发送请求,根域名服务器会告诉本地 DNS 服务器去查询哪个顶级域名服务器。
- 本地域名服务器向顶级域名服务器发起查询请求,顶级域名服务器会告诉本地 DNS 服务器,去查找哪个权限域名服务器。
- 本地域名服务器向权限域名服务器发起查询请求,权限域名服务器告诉本地域名服务器请求域名所对应的IP地址。(3,4,5被称为迭代查询)。
- 最后,本地域名服务器告诉客户端请求域名所对应的IP地址。
网络协议的分层
- 物理层
- 数据链路层
- 网络层
- 传输层
- 会话层
- 表示层
- 应用层
TCP/IP 协议
"TCP/IP 协议"不仅仅指的是 TCP 和 IP 两个协议,⽽是指的⼀个由 FTP,SMTP,TCP,UDP,IP,ARP 等等协议构成的协议集合。
TCP/IP 协议将应用层、表示层、会话层合并为应用层,物理层和数据链路层合并为网络接口层。
- 网络接口层(物理层,数据链路层)
- 网络层
- 传输层
- 应用层(会话层,表示层,应用层)
三次握手
- 第一次握手: 客户端发送 SYN=1 和随机数 Seq 的包给服务器。第一次握手,表示客户端需要建立连接。
- 服务端发送 ACK, ACK的值是第一次握手 Seq 的值加 1 以及 SYN=1, 和随机数 Seq 的包给客户端。第二次握手表示,服务端告诉客户端可以建立连接,你可以发送了。
- 客户端会检测 ACK 是否正确(是否等于第一次握手的 Seq+1)。如果正确,客户端会发送服务端的 ACK,ACK等于第二次握手的 Seq+1,服务端收到后检测 ACK 是否正确(是否等于第二次握手的Seq+1),如果正确表示连接成功。第三次握手表示,客户端告诉服务端我马上准备发送了。
为什么是三次握手
- 为什么不是二次握手? TCP 是可靠的,需要确认双方的接收和发送能力。第一次握手确认了客户端的发送能力。第二次握手确认了服务端的发送能力,和接收能力。第三次握手确认了客户端的接收能力。
- 为什么不是四次握手?浪费资源
TCP 和 UDP 的区别
- TCP 需要先建立连接后,才会发送数据。UDP 不需要建立连接,就会发送数据。
- TCP 提供安全性和可靠性。UDP 不保证。
- TCP 是点对点连接的,UDP 一对一,一对多,多对多都可以。
- TCP 传输效率相对较低, 而 UDP 传输效率高。
- TCP 适合用于网页,邮件等; UDP 适合用于视频,语音广播等
- TCP 逻辑通信是全双工的可靠信道,UDP 则是不可靠信道。
- TCP 首部开销大, 20 个字节;UDP 首部仅有 8 个字节。
什么是单工、半双工和全双工通信?
- 单工, 只支持数据在一个方向上传输
- 半双工, 允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信。
- 全双工, 允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合。
TLS 四次握手
- 第一次握手:客户端发送支持的加密算法给服务端
- 第二次握手:服务端返回公钥(用于公钥用于加密,对称加密的密钥)
- 第三次握手:客户端发送使用公钥加密过的,对称加密的密钥,给服务端。并通知服务端后面的数据段会使用对称加密传输。
- 第四次握手:服务端发送消息,通知客户端后面的数据段会加密传输;TLS握手结束。
http 报文的组成结构
请求报文

- 请求行: 请求方法 | URL | HTTP协议
- 请求 Header
- 空行(通知服务器以下是请求体)
- 请求体
响应报文

- 响应行: HTTP协议 | 状态码
- 响应 Header
- 空行(通知服务器以下是响应体)
- 响应体
http 协议和 TCP 协议之间的关系
- DNS 协议,用于解析域名
- Http 协议,用于生成请求报文
- TCP 协议,将请求报文按序号分割成多个报文段
- IP 协议,负责搜索和传送报文段
- TCP 协议,将报文段按顺序合并
- Http 协议,将报文返回给服务度
响应会同样的顺序进行回传
TCP 是如何保证可靠性的
- TCP 的连接是基于三次握手,保证了连接的可靠性
- TCP 的断开连接基于四次挥手,保证了断开的可靠性
- TCP 是可控制,可以控制传输的速度以及重重传。它有数据包校验、ACK 应答、超时重传(发送方)、失序数据重传(接收方)、丢弃重复数据、流量控制(滑动窗口)和拥塞控制等机制。
TCP 超时重传
最基本的重传机制,就是超时重传。在发送数据报文时,设定一个定时器,每间隔一段时间,没有收到对方的 ACK 确认应答报文,就会重发该报文。首先了解下什么是 RTT。RTT,一个数据包从发出去到回来的时间,即数据包的一次往返时间。超时重传时间,简称 RTO。一般情况下,RTO略大于RTT。
TCP 滑动窗口
发送端的窗口:

接收端的窗口:

TCP 发送一个数据,需要收到确认应答,才会发送下一个数据。这样有个缺点,就是效率会比较低。为了解决这个问题,TCP 引入了窗口,它是操作系统开辟的一个缓存空间。窗口大小值表示无需等待确认应答,可以继续发送数据的最大值。(说白了滑动窗口就是一个缓冲区)
TCP 报文首部有字段,16位窗口大小,它告诉对方本端的TCP接收缓冲区(滑动窗口)还能容纳多少字节的数据,这样对方就可以控制发送数据的速度,从而达到流量控制的目的。
TCP 拥塞控制
拥塞控制是作用于网络的,防止过多的数据包注入到网络中,避免出现网络负载过大的情况。
发送方维护一个拥塞窗口 cwnd(congestion window)的变量,用来估算在一段时间内这条链路可以承载和运输的数据的数量。它大小代表着网络的拥塞程度,并且是动态变化的,如何获取 cwnd 的大小呢?如果没有出现阻塞,可以逐渐增加 cwnd 的大小。当出现阻塞 cwnd 就应该减小一些。
TCP 通过, 慢启动, 拥塞避免, 拥塞发生, 快速恢复等几种方法实现拥塞控制
慢启动
TCP 建立连接后,一开始不会发送大量的数据,而是由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,每收到一个 ACK,就将拥塞窗口 cwnd 大小就加1(单位是 MSS)。每轮发送窗口增加一倍,呈指数增长,如果出现丢包,拥塞窗口就减半,进入拥塞避免阶段。当 cwnd 增加到一定的阀值(慢启动阀值 ssthresh)后,就会进入拥塞避免的阶段。
拥塞避免
慢启动时 cwnd 的增长是指数级的增长,当 cwnd 大于慢启动阀值后,就会进入拥塞避免算法,cwnd 的增长是线性的。当逐渐增大后产生了丢包的情况时,就会产生拥塞发生。
拥塞发生
当发生超时重传后,慢启动阀值(ssthresh)会被设置为当前的 cwnd/2, cwnd 设置为 1,然后重新进入慢启动过程
Connection: keep-alive
响应头上添加 Connection: keep-alive 实现了长连接了。这里的长连接指的是 TCP 的长连接。而不是 HTTP 的连接。TCP 长连接可以复用一个 TCP 连接来发起多次 HTTP 请求。HTTP1.1 默认是长连接,而 HTTP 1.0 协议也支持长连接,但是默认是关闭的。
长连接
在响应头上添加 Connection: keep-alive 实现了长连接了。HTTP1.1 默认是长连接。
可以在响应头上添加 Keep-Alive: timeout=15, max=100, 代表 15 s后超时,最多支持 100个 HTTP请求
四次挥手
- 第一次挥手: 客户端发送 FIN,告诉服务端,自己准备关闭。
- 第二次挥手: 服务端发送 ACK, 确认了客户端准备关闭的消息。
- 第三次挥手:服务端发送 FIN,告诉客户端,自己准备关闭。
- 第四次挥手: 客户端在接收到服务端准备关闭的消息后,最后一次发送 ACK 确认包。并进入等待状态,如果客户端一段时间后没有收到服务端回复的 ACK ,就可以认为服务端已经关闭了。客户端就会关闭连接。
为什么是四次挥手

客户端没有消息后,不能确保服务端没有消息发送,所以需要服务端向客户端告知,我没有消息了。
http1.0 & http1.1
1.0
默认不开启长连接,如果需要开启长连接,需要在响应头添加Connection: keep-alive
1.1
- 默认开启了长连接,TCP 连接默认不关闭,可以被多个请求复用。
- 增加了更多的缓存策略(Cache-Control、Etag/If-None-Match)
- 新增了新的状态码
- 引入了管道机制,即在同一个 TCP 连接里面,客户端可以同时发送多个请求。
http 中提升传输速率的方式有哪些
- DNS Prefetching, DNS预解析。在页面中添加
- 域名收敛, 将静态资源只放在一个域名下面,可以有效减少 dns 的请求。
CDN
内容分发网络,是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络。
CDN 的工作原理
- 用户发起 URL 请求
- DNS 高速缓存进行递归查询,如果有 IP 直接返回。如果没有则进行 DNS 迭代查询
- CDN 的 DNS 专用服务器,会去查询,CDN 中处于负载均衡的设置
- 查询到 CDN 负载均衡设备的服务器后,CDN 的 DNS 服务器会返回用户的最佳 IP
- 用户获取到 IP 地址后,会根据 IP 地址访问对应的服务器。
- 如果该 IP 地址对应的节点已缓存该资源,则会将数据直接返回给用户
- 如果该 IP 地址对应的节点未缓存该资源,则节点向源站发起对该资源的请求。
CDN 的优势
- 解决因分布,带宽,服务器性能, 带来的访问延迟问题。用户可就近取得所需内容。
- 可以保护网站安全,CDN 的负载均衡和分布式存储技术,可以加强网站的可靠性。
https
HTTPS 并非是应用层的一种新协议。HTTPS 可以看作 SSL/TLS + HTTP。通过 SSL/TSL 实现加密和解密。HTTP 对加密的内容进行传输
- HTTPS 需要用到 SSL 证书,而 HTTP 不用。(HTTPS 先和 SSL 通信,再由 SSL 和 TCP 通信了,HTTP 直接和 TCP 通信)
- HTTPS 是密文传输,HTTP 是明文传输
- HTTPS 标准端口443,HTTP 标准端口80
- HTTPS 安全,HTTP 不安全
- HTTPS 通信会消耗更多服务器的 CPU 和内存资源(因为存在加密解密的过程)
TLS/SSL
- SSL,即 Secure Sockets Layer(安全套接层协议),是网络通信提供安全及数据完整性的一种安全协议。
- TLS,即 Transport Layer Security(安全传输层协议),它是 SSL 3.0 的后续版本。
对称加密 和 非对称加密
- 对称加密,加密和解密使用同一个秘钥
- 非对称加密,有两个秘钥,公钥和私钥。使用公钥对信息进行加密处理。使用私钥解密。
工作流程
HTTPS 是在 HTTP 上建立 SSL 加密层,并对传输数据进行加密,是 HTTP 协议的安全版。https 使用对称加密(用来发送内容) + 非对称加密(用来传输用于对称加密的密钥)。使用非对称加密速度比较慢,所以非对称加密仅仅用来传输对称加密的密钥。
- Client发起一个 HTTPS 的请求,根据 RFC2818 的规定,Client 默认连接 Server 的 443(默认)端口。
- Server 把事先配置好的数字证书返回给客户端。
- Client 验证数字证书(数字证书中包含了公钥)。如果证书不通过,则弹出警告框。
- Client 生成对称密钥(用于对称加密的密钥),然后用之前证书的公钥加密这个对称密钥,发给 Server。
- Server 使用自己的私钥解密经过公钥加密的消息,得到 Client 生成对称密钥。目前为止,Client 和 Server 双方都持有了相同的对称密钥。
- Server 使用对称密钥加密"明文内容A",发送给 Client。
- Client 使用对称密钥解密响应的密文,得到"明文内容A"。
- Client再次发起 HTTPS 的请求,使用对称密钥加密请求的"明文内容B",然后 Server 使用对称密钥解密密文,得到"明文内容B"。
http2 和 http1.1 的区别
- http2 采用二进制传输,http1.1 采用文本传输
- http2 将请求和响应数据,分割为更小的帧,它们采用二进制编码
- http1.1 将请求和响应数据则是以文本换行符分隔
- http2 支持多路复用, http1.1 不支持多路复用
- http1.1 提供了 keep-live,支持一个 tcp 链接,发送多个 http 请求。但是请求的接收必须是有序的,串行的。Chrome 最大支持同一个域名发起 6 个 TCP 连接,http1.1实现的是 TCP 的并行,而不是 http 请求的并行。
- http2,同域名下所有通信都在单个连接上完成,同一个 TCP 连接可以同时存在多个 HTTP 请求。
- http2 支持服务器主动推送,http1.1 不支持主动推送,当然主动推送也遵守同源策略
- http2 支持头部信息压缩, http1.1 不支持头部压缩
http1.1 的管道化和 http2 多路复用的区别
- http1.1 的管线化,可以一次性在一个 TCP 连接里,发送请求,但是在接收响应的时候,也必须依顺序接收,如果前一个请求遇到了阻塞,后面的请求即使已经处理完毕了,仍然需要等待阻塞的请求处理完毕。
- http2 多路复用,即使前一个请求被阻塞,但是不影响后序请求的接收。
为什么 http1.1 不能实现多路复用
http1.1 基于文本传输的,必须按照顺序传输。否则接收后无法正确的拼接。http2 基于帧传输,即使没有按照顺序传送,可以根据帧的 id 的重新组装。
队头阻塞
http 规定报文必须是"一发一收",这就形成了一个先进先出的"串行"队列(即使是 http1.1 实现了管道化也要求实现串行)。
队列里的请求没有轻重缓急的优先级,只有入队的先后顺序,排在最前面的请求被最优先处理。如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求也不得不跟着一起等待,结果就是其他的请求承担了不应有的时间成本。这就是队头阻塞。
http3
http2 的缺点
- http2 基于 TCL 连接, 所以7次握手(TCP3次握手 + TLS4次握手),有很长时间的延迟
- http2 没有解决队头阻塞的问题
http3 的改进
- http3使用基于 udp 的 QUIC 协议,解决了队头阻塞,不需要"握手"和"挥手。
接口如何防刷
- 网关控制流量洪峰,对在一个时间段内出现流量异常,可以拒绝请求。
- 对请求来源的 ip 请求个数做限制。
- http 请求头信息校验;(例如 host,User-Agent,Referer)
- 人机验证,验证码,短信验证码,滑动图片形式
- 拦截器特定信息校验,例如:token
扫码登录的原理
- pc 端请求生成二维码,服务端生成一个 uuid,会将 uuid 作为 key 存入 redis,同时这个 key 必须设置一个过期时间。同时 uuid 会返回给 pc 端。pc 端会根据 uuid 生成一个二维码,同时 pc 端会不断的轮训判断是否登录。如果登录了就进行跳转。直到二维码失效。(如果不设置过期时间会一直轮训)。
- 用户打开手机 APP 进行扫描(手机 APP 是已经登录过的,不然没有办法扫码),手机端会将 token 和 uuid 进行提交到服务端。服务器会判断 token 是否合法,如果合法则将token 作为 value 存到 redis 中。
- 由于 pc 客户端还在不断的轮询请求,当判断 value 已经存入 redis 后,说明已经成功登录,服务器将 token 回传给 pc 端。pc 确认登录,页面跳转就完成了扫码登录。
传输图片的过程中如果突然中断,如何在恢复后从之前的中断中恢复传输?
使用断点续传。客户端对文件切片,同时前端或者服务端需要记住已上传的切片。每次上传前,服务端把以上传的切片名返回,前端再跳过这些已经上传切片,这样就实现了"续传"的效果。