常见网络和优化基础问题积累
1. 什么是跨域,什么是同源策略?
在前后端分离的模式下,前后端域名是不一致的,此时就会发生跨域访问的问题。
跨域问题来源于 JavaScript 的同源策略,只有协议,主机名和端口号都相同的情况下才允许互相访问,即使两个不同的域名指向同一个 ip 地址,也不是同源。对于其他的源,需要有明确授权的情况下才能读写对方的资源。
2. 减少页面加载时间的方式
- 减少 http 请求如:合并图片(csssprite,svgsprite),合并文件。
- 适当减小图片尺寸和清晰度。
- 在浏览器支持的情况下使用 webp 在保留图片质量的同时减小图片体积。
- 优化 CSS 代码:(合并重复 css,降低 css 选择器的复杂性等等)。
- 将一些脚本样式和静态资源托管到 cdn。
- 服务端启用 gzip 功能。浏览器再将 gzip 解压。
- 减少 cookie 的体积,cookie 太多会拖慢请求速度。
- 脚本使用 defer 或 async 延迟加载。
- 服务器预渲染,适用于静态网站。
3. 什么是 jsonp?
jsonp 就是 JSON with Padding 的略称,是民间提出的一种跨域解决方案,通过客户端的 script 标签发出的请求方式。
同源策略禁止我们使用脚本访问非同源下的资源,但通过一些标签发出的请求则不会被进行同源检查,如:script,link,img 标签。
实现过程如下:
- 准备一个全局接收函数
window.myCallback = (res) => {
//声明一个全局函数 'callback',用于接收响应数据
console.log(res)
}
- 在 html 创建 script 标签,发出请求
<script>
window.myCallback = (res) => {
//声明一个全局函数 'callback',用于接收响应数据
console.log(res)
}
</script>
<script url="xxx?callback=myCallback">
// script标签的请求必须在写在定义全局函数之后
// 这里需将全局函数的函数名作为参数callback的value传递
// 这里callback这个键名是前后端约定好的
</script>
- 服务端接收到请求,将如下数据响应回来
myCallback({
name: 'ahreal',
age: 18,
})
最后我们就可以拿到请求的数据了。
注意这一步也是需要后台配合才可以的,并不是前端写这些代码就能实现的。
4. HTTP 报文结构是怎样的?
报文大致结构是: header
+ body
具体点就是:起始行 + 头部 + 空行 + 实体
起始行
对于请求报文来说,起始行类似这样:GET /home HTTP/1.1
也就是 方法 + 路径 + http 版本。
对于响应报文来说,起始行一般是这个样:HTTP/1.1 200 OK
。响应报文的起始行也叫做状态行。由 http 版本、状态码和原因 三部分组成。
空行
用来区分开头部和实体,如果说在头部中间故意加一个空行,那么空行后的内容全部被视为实体。
实体
表示具体的数据,请求报文对应请求体, 响应报文对应响应体。
5. 如何理解 HTTP 的请求方法?
http/1.0 规定了以下方法:
- GET: 通常用来获取资源,幂等
- HEAD: 获取资源的元信息,幂等
- POST: 提交数据,即上传数据,非幂等
http/1.1 新增了以下请求方法:
- PUT: 更新某个较为完整的资源,幂等
- DELETE: 删除资源(几乎用不到),幂等
- CONNECT: 建立连接隧道,用于代理服务器,非幂等
- OPTIONS: 列出可对资源实行的请求方法,用来跨域请求,幂等
- TRACE: 追踪请求-响应的传输路径,幂等
- PATCH: 用于资源的部分内容的更新,非幂等
6. GET 和 POST 有什么区别?
- 缓存:GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。
- 编码:GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
- 参数:GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
- 幂等:在 RFC 文档中定义:GET 应该是幂等且安全的,而 POST 不是。
幂等表示:1-N 个相同请求的副作用与单个请求相同。
7. 如何理解 URI?
URI,也就是统一资源标识符,它的作用很简单,就是区分互联网上不同的资源。
8. 如何理解 HTTP 状态码?
RFC 规定 HTTP 的状态码为三位数,被分为五类:
- 1xx: 表示目前是协议处理的中间状态,还需要后续操作。
- 101 Switching Protocols。在 HTTP 升级为 WebSocket 的时候,如果服务器同意变更,就会发送状态码 101。
- 2xx: 表示成功状态。
- 200 OK 是见得最多的成功状态码。通常在响应体中放有数据。
- 204 No Content 含义与 200 相同,但响应头后没有 body 数据。
- 206 Partial Content 顾名思义,表示部分内容,它的使用场景为 HTTP 分块下载和断点续传,当然也会带上相应的响应头字段 Content-Range。
- 3xx: 重定向状态,资源位置发生变动,需要重新请求。
- 301 Moved Permanently 即永久重定向,比如你的网站从 HTTP 升级到了 HTTPS 了,以前的站点再也不用了,应当返回 301,这个时候浏览器默认会做缓存优化,在第二次访问的时候自动访问重定向的那个地址。
- 302 Found 临时重定向,如果网址只是暂时不可用,那么直接返回 302 即可,和 301 不同的是,浏览器并不会做缓存优化。
- 304 Not Modified: 当协商缓存命中时会返回这个状态码。
- 4xx: 请求报文有误。
- 400 Bad Request: 请求无效,通常由于前端提交的字段与后台接收的不一致。
- 401 Authentication Required:表示用户无权访问。
- 403 Forbidden: 这实际上并不是请求报文出错,而是服务器禁止访问,原因有很多,比如法律禁止、信息敏感。
- 404 Not Found: 资源未找到,表示没在服务器上找到相应的资源。
- 405 Method Not Allowed: 请求方法不被服务器端允许。
- 406 Not Acceptable: 指代服务器端无法提供与
Accept-Charset
以及Accept-Language
消息头指定的值相匹配的响应。 - 408 Request Timeout: 服务器等待了太长时间,请求发送到该网站服务器(即请求加载网页)花的时间比该网站的服务器准备等待的时间要长。
- 409 Conflict: 多个请求发生了冲突。
- 413 Request Entity Too Large: 请求体的数据过大。
- 414 Request-URI Too Long: 请求行里的 URI 太大。
- 429 Too Many Request: 客户端发送的请求过多。
- 431 Request Header Fields Too Large请求头的字段内容太大。
- 5xx: 服务器端发生错误。
- 500 Internal Server Error: 仅仅告诉你服务器出错了,出了啥错咱也不知道。
- 501 Not Implemented: 表示请求的方法不被服务器支持,因此无法被处理。服务器必须支持的方法。
- 502 Bad Gateway: 表示作为网关或代理角色的服务器,从上游服务器(如 tomcat、php-fpm)中接收到的响应是无效的。。
- 503 Service Unavailable: 表示服务器当前很忙,暂时无法响应服务。
9. 简要概括一下 HTTP 的特点?HTTP 有哪些缺点?
特点
- 灵活可扩展:一个是语义上的自由,只规定了基本格式,比如空格分隔单词,换行分隔字段,其他的各个部分都没有严格的语法限制。另一个是传输形式的多样性,不仅仅可以传输文本,还能传输图片、视频等任意数据,非常方便。
- 可靠传输:HTTP 基于 TCP/IP,因此把这一特性继承了下来。这属于 TCP 的特性,不具体介绍了。
- 请求-应答:也就是一发一收、有来有回,一个请求对应一个应答。
- 无状态:这里的状态是指通信过程的上下文信息,而每次 http 请求都是独立、无关的,默认不需要保留状态信息。
10. 预加载和懒加载的区别
预加载指的是页面在加载完成后,提前将所需资源下载,之后使用的时候从缓存调用;懒加载是延迟加载,按照一定的条件或者需求等到满足条件的时候再加载对应的资源。
使用预加载,网页的加载速度将会非常快,适合大图很多的网站。而使用懒加载可以缓解服务器的压力。
11. HTTP1.0/1.1/2.0 在并发请求上的主要区别是什么?
- HTTP1.0:短连接,每次 TCP 连接只对应一个请求,当服务器响应后,连接断开,下一个请求需要重新建立 TCP 连接,需要声明
Connection: keep-alive
才行,默认支持 100 个 http 请求。 - HTTP1.1:默认采用长连接,不用声明
Connection: keep-alive
,增加了管道机制,在同一个 TCP 连接中允许多个请求同时发送,但是服务器需要按照顺序一个一个响应。在同一个 TCP 连接中,所有的数据通信是按照顺序进行的,如果一个请求响应慢,后面的请求都会被卡住,造成队头堵塞。 - HTTP2.0:加入了双工模式,不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求。使用多路复用技术,同一个 TCP 连接可以并发处理多个请求。增加服务器推送,实现服务端主动向客户端发送数据的功能。
HTTP2 仍然没有解决队头堵塞问题,因为 HTTP2 会把一次传输所有的文件都放在一个 TCP 连接中,只要这个 TCP 中发生一个丢包,连接就必须重新建立,之前所有传输内容进行必须重传。
12. 长连接和多路复用的区别?
长连接:同一时间一个 TCP 连接只能够处理一个请求,上一个请求响应后才能处理下一个请求。浏览器有最大 TCP 连接数的限制,因此有最大并发请求数的限制。
多路复用:同域名下所有通信都在单个连接上完成,消除了因为多个 TCP 连接而带来的延时和内存消耗。单个连接上可以并行交错的请求和响应,之间互不干扰。并发请求的数量比长连接大了好几个量级。
13. 为什么 HTTP1.1 不能实现多路复用?
HTTP1.1 是基于文本分割解析的协议,而 HTTP2 是基于二进制帧的协议。
HTTP1.1 的报文结构中,服务器需要不断地读入字节,直到遇到换行符,或者说一个空白行;处理顺序的串行的,一个请求和一个响应需要通过一问一答的形式才能连接起来。
HTTP2.0 中存在帧和流两个概念。帧代表最小数据单位,每个帧会标识出帧属于哪个流,流就是多个帧组成的数据流。多路复用就是在一个 TCP 连接中可以存在多条流,也就是可以发送多个请求,两端可以通过帧中的标识知道该帧属于哪个流(请求)。
14. 什么是 keep-alive
Connection
决定当前事务(一次三次握手和四次挥手)完成后,是否会关闭网络连接。
Connection: keep-alive
表示持久性连接,即一次事务完成后不关闭网络连接。
Connection: close
表示非持久性连接,即一次事务完成后关闭网络连接。
keep-alive
有两个参数,它们以逗号分隔,第一个表示空闲连接保持打开状态的最短时间(秒),第二个表示关闭连接之前可以在次连接上发送的最大请求数:
Connection: Keep-Alive
Keep-Alive: timeout=5, max=997
keep-alive
可以缓解 http1.0 短连接带来的效率问题,但仍有缺点:
- 串行的文件传输。
- 同域名下并行请求限制带来的阻塞(6-8)个。
15. TCP 和 UDP 的区别
TCP 面向连接协议,传输可靠,以字节流传输;传输效率慢,所需资源多;在场景要求通信数据可靠的请况下使用如文件传输,邮件发送等。报文首部字节 20-60。TCP 保证数据传输的顺序和正确性。
UDP 无连接协议,传输不可靠,以数据报文段传输;传输效率快,所需资源少;在对通信速度要求高的场景下使用如域名转换,视频音频等。报文首部 9 个字节。UDP 不保证数据传输的顺序和正确性。
16. 什么是 QUIC?QUIC 基于 UDP 怎么保证可靠性?
QUIC(Quick UDP Internet Connections)是 Google 基于 UDP 提出的一种改进的通信协议。也称为 HTTP3.0。
QUIC 使用 UDP 来传输数据以加快网络速度,降低延迟,由 QUIC 来保证数据的顺序、完整性和正确性,即使发生了丢包,也由 QUIC 来负责数据的纠错。
QUIC 集成了 TCP + HTTPS + HTTP/2 的功能,QUIC 连接基于 Diffie-Hellman 的加密算法。
17. 预渲染和 SSR 的区别
用户请求前的服务器渲染即为「预渲染」。一般用于静态站点。预渲染是直接返回给浏览器真正 html 页面,因此不会执行里面的 js 脚本。
用户请求后的服务器渲染即为「服务端渲染」,需要经过解析执行 JS => 构建 HTML 页面 => 输出给浏览器。
18. CSR 和 SSR 的优缺点
服务端渲染的优缺点:
- 前端页面加载快,只负责渲染。
- 有利于网站的 SEO,后端有完整的 html 页面,所以爬虫更容易爬取获得信息。
- 不利于前后端分离,开发效率低。
- 占用服务器端资源。
客户端渲染的优缺点:
- 有利于前后端分离。
- SAP 的页面切换体验更好。
- 首屏加载慢,需要许多优化。
- 不利于 SEO。
19. 什么是 gRPC?gRPC 相比 http(Restful API) 的优势?
gRPC 是一个高性能开源 RPC 框架。
RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,而且也遵从 server/client 模型。使用的时候客户端调用 server 端提供的接口就像是调用本地的函数一样。
和 Restful API 一样,gRPC 也使用 http 作为底层传输协议。但 gRPC 使用的 http2.0,而 restful api 则不一定。
- gRPC 可以通过 protobuf 来定义接口,可以有更加严格的接口约束条件,支持多种语言。
- protobuf 可以将数据序列化为二进制编码,这会大幅减少需要传输的数据量,从而大幅提高传输速度。
- gRPC 可以支持 streaming 流式通信(http2.0),提高传输速度。
20. DNS 预解析是什么?有什么用?
DNS 解析时间可能导致大量用户感知延迟,DNS 预解析可以减少这种情况的发生。
浏览器对网站第一次的域名 DNS 解析查找流程依次为:浏览器缓存-系统缓存-路由器缓存-ISP DNS 缓存-递归搜索。
DNS 预解析是浏览器试图在用户访问链接之前解析域名。域名解析后,如果用户确实访问该域名,那么 DNS 解析时间将不会有延迟。
遇到网页中的超链接,DNS prefetching 从中提取域名并将其解析为 IP 地址,这些工作在用户浏览网页时,使用最少的 CPU 和网络在后台进行解析。
在某些浏览器中这个预读取的行为将会与页面实际内容并行发生(而不是串行)。正因如此,某些高延迟的域名的解析过程才不会卡住资源的加载。
你可以通过在服务器端发送 X-DNS-Prefetch-Control
报头,或是在文档中使用值为 http-equiv
的标签。
<meta http-equiv="x-dns-prefetch-control" content="off" />
你可以通过使用 rel
属性值为 link type
中的 dns-prefetch
的标签来对特定域名进行预读取:
<link rel="dns-prefetch" href="http://www.xuanfengge.com/" />
Chrome 会记住最近使用的 10 个 domain,并且在开启浏览器时自动解析,因此在打开这些常用页面的时候,并不会有 DNS Lookup 的延迟情况。
chrome 使用 8 个线程专门做 DNS Prefetching,而且 chrome 本身不做 dns 记录的 cache,是直接从操作系统读 dns。所以直接修改系统的 dns 记录或者 host 是可以直接影响 chrome。
21. A,B 机器正常连接后,B 突然重启,A 此时处于 TCP 什么状态?
B 会在重启之后进入 TCP 的 listen 状态,只要 A 重新发送数据包,不管是什么包,B 应该会主动发送一个带有 RST 位的重置包进行连接重置,所以 A 应该在 SYN_SENT 状态。
22. Chrome 可以并行下载多少个资源?
6 个,同一时间针对同一域名下的请求有一定数量限制,超过限制数目的请求会被阻塞。大多数浏览器的并发数量都控制在 6 以内。有些资源的请求时间很长,因而会阻塞其他资源的请求。因此,对于一些静态资源,如果放到不同的域名下面就能实现与其他资源的并发请求。
23. webSocket 如何兼容低浏览器?
使用轮询或长连接的方式实现伪 websocket 的通信。
24. 长轮询和短轮询的区别?
长轮询是服务器收到请求后如果有数据, 立刻响应请求; 如果没有数据就会 hold 一段时间,这段时间内如果有数据立刻响应请求; 如果时间到了还没有数据, 则响应 http 请求;浏览器受到 http 响应后立即发送一个同样 http 请求查询是否有数据。
短轮询是服务器收到请求不管是否有数据都直接响应 http 请求; 浏览器受到 http 响应隔一段时间在发送同样的 http 请求查询是否有数据;
25. Web 应用从服务器主动推送数据到客户端有哪些方式?
- 短轮询,利用 setInterval 定时像服务器发送请求。
- 长轮询,在后端数据没有更新的时候不再返回空响应,而且后端一直保存连接,直到后端有数据变化,则相应请求并且关闭连接,前端收到数据,马上再次向后端发起请求,并处理刚刚收到的数据。
- WebSocket 真正意义上的主动推送。
26. 304 缓存原理?
服务器首先产生 ETag,ETag 一般为资源的哈希值,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端将该记号通过 If-None-Match 传回服务器要求服务器验证其(客户端)缓存。
304 是 HTTP 状态码,服务器用来标识这个文件没修改,不返回内容,浏览器在接收到个状态码后,会使用浏览器已缓存的文件。
27. TLS 握手做了什么?
任何通信使用 HTTPS 都会发生 TLS 握手。
通过 TCP 握手打开 TCP 连接后,会发生 TLS 握手。在 TLS 握手过程中,客户端和服务器将共同执行以下操作:
- 指定将使用的 TLS 版本(TLS 1.0、1.2、1.3 等)。
- 确定将使用哪些加密套件。
- 通过服务器的公钥和 SSL 证书颁发机构的数字签名来验证服务器的身份。
- 握手完成后,生成会话密钥以使用对称加密。
28. 网络分层里七层模型是哪七层?
- 应用层:应用层、表示层、会话层(从上往下)(HTTP、FTP、SMTP、DNS)。
- 传输层(TCP 和 UDP)。
- 网络层(IP)。
- 物理和数据链路层(以太网)。
每一层的作用如下:
- 物理层:通过媒介传输比特,确定机械及电气规范(比特 Bit)。
- 数据链路层:将比特组装成帧和点到点的传递(帧 Frame)。
- 网络层:负责数据包从源到宿的传递和网际互连(包 PackeT)。
- 传输层:提供端到端的可靠报文传递和错误恢复(段 Segment)。
- 会话层:建立、管理和终止会话(会话协议数据单元 SPDU)。
- 表示层:对数据进行翻译、加密和压缩(表示协议数据单元 PPDU)。
- 应用层:允许访问 OSI 环境的手段(应用协议数据单元 APDU)。
29. 一个图片 url 访问后直接下载怎么实现?
<a download href="pic.png">aaa</a>
30. 一句话概括 restful
就是用 URL 定位资源,用 HTTP 描述操作。
31. cookie 可以设置哪些字段?
name
字段为一个cookie
的名称。value
字段为一个cookie
的值。domain
字段为可以访问此cookie
的域名。- 非顶级域名,如二级域名或者三级域名,设置的
cookie
的domain
只能为顶级域名或者二级域名或者三级域名本身,不能设置其他二级域名的cookie
,否则cookie
无法生成。顶级域名只能设置domain
为顶级域名,不能设置为二级域名或者三级域名,否则cookie
无法生成。 - 二级域名能读取设置了
domain
为顶级域名或者自身的cookie
,不能读取其他二级域名domain
的cookie
。所以要想cookie
在多个二级域名中共享,需要设置domain
为顶级域名,这样就可以在所有二级域名里面或者到这个cookie
的值了。顶级域名只能获取到domain
设置为顶级域名的cookie
,其他domain
设置为二级域名的 无法获取。
- 非顶级域名,如二级域名或者三级域名,设置的
如
yangbai.com
能设置domain
为yangbai.com
或者www.yangbai.com
,但不能设置domain
为login.yangbai.com
,这样cookie
不会生成。
path
字段为可以访问此cookie
的页面路径。 比如domain
是abc.com
,path
是/test
,那么只有/test
路径下的页面可以读取此cookie
。expires/Max-Age
字段为此cookie
超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie
失效。不设置的话默认值是 Session,意思是cookie
会和session
一起失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie
失效。size
字段此cookie
大小。http
字段cookie
的httponly
属性。若此属性为true
, 则只有在http
请求头中会带有此cookie
的信息,而不能通过document.cookie
来访问此cookie
。secure
字段 设置是否只能通过 https 来传递此条cookie
。
32. 顶级域名,一级域名,二级域名
域名级数是指一个域名由多少级组成,域名的各个级别被 .
分开。
顶级域名在开头有一个点,如 .XXX
,也叫做一级域名。
二级域名就是在顶级域名前再加一级,如 XXX.XXX
。在域 example.co.uk
中,co
是二级域。
33. cookie 编码方式?
encodeURI()
34. PUT 和 POST 可以给服务器发送新增资源,有什么区别?
PUT
和 POST
⽅法的区别是,PUT
⽅法是幂等的:连续调⽤⼀次或者多次的效果相同(无副作⽤),⽽ POST 方法是非幂等的。
除此之外还有⼀个区别,通常情况下,PUT
的 URI
指向是具体单⼀资源,⽽ POST
可以指向资源集合。
举个例⼦,我们在开发⼀个博客系统,当我们要创建⼀篇⽂章的时候往往⽤ POST https://www.jianshu.com/articles
,这个请求的语义是,在 articles
的资源集合下创建⼀篇新的⽂章,如果我们多次提交这个请求会创建多个文章,这是非幂等的。
35. PUT 和 PATCH 都是给服务器发送修改资源,有什么区别?
与 POST
方法类似,PATCH
方法是非幂等的,这就意味着连续多个的相同请求会产生不同的效果。
PATCH
应该用于部分数据的更新,而 PUT
则是整个数据的覆盖。
36. HTTPS 如何保证安全?
过程⽐较复杂,我们得先理解两个概念
对称加密:即通信的双⽅都使⽤同⼀个秘钥进⾏加解密,⽐如特务接头的暗号,就属于对称加密
对称加密虽然很简单性能也好,但是⽆法解决⾸次把秘钥发给对⽅的问题,很容易被⿊客拦截秘钥。
⾮对称加密:
- 私钥 + 公钥= 密钥对
- 即⽤私钥加密的数据,只有对应的公钥才能解密,⽤公钥加密的数据,只有对应的私钥才能解密
- 因为通信双⽅的⼿⾥都有⼀套⾃⼰的密钥对,通信之前双⽅会先把⾃⼰的公钥都先发给对⽅
- 然后对⽅再拿着这个公钥来加密数据响应给对⽅,等到到了对⽅那⾥,对⽅再⽤⾃⼰的私钥进⾏解密
⾮对称加密虽然安全性更⾼,但是带来的问题就是速度很慢,影响性能。
解决⽅案:
那么结合两种加密⽅式,将对称加密的密钥使⽤⾮对称加密的公钥进⾏加密,然后发送出去,接收⽅使⽤私钥进⾏解密 得到对称加密的密钥,然后双⽅可以使⽤对称加密来进⾏沟通。
此时⼜带来⼀个问题,中间⼈问题:
如果此时在客户端和服务器之间存在⼀个中间⼈,这个中间⼈只需要把原本双⽅通信互发的公钥,换成⾃⼰的公钥,这样中间⼈就可以轻松解密通信双⽅所发送的所有数据。
所以这个时候需要⼀个安全的第三⽅颁发证书(CA),证明身份的身份,防⽌被中间⼈攻击。
但是问题来了,如果中间⼈篡改了证书,那么身份证明是不是就⽆效了?这个证明就⽩买了,这个时候需要⼀个新的技术,数字签名。
数字签名就是⽤ CA ⾃带的 HASH 算法对证书的内容进⾏ HASH 得到⼀个摘要,再⽤ CA 的私钥加密,最终组成数字签名。
当别⼈把他的证书发过来的时候,我再⽤同样的 Hash 算法,再次⽣成消息摘要,然后⽤ CA 的公钥对数字签名解密,得到 CA 创建的消息摘要,两者⼀⽐,就知道中间有没有被⼈篡改了。
37. ping 一个 IP 地址时发生了什么?
ping
实际上发送了 ICMP ECHO_REQUEST
的报文。
通过让目标 IP 地址返回 ICMP ECHO_RESPONSE
报文来判断 IP 可不可达。
ICMP
分为 Query
查询报文及 Error Message
报文,ping
为查询报文。
38. TLS/SSL 四次握手
ClientHello
客户端提供的信息:
- 支持的协议版本,比如 TLS 1.0 版。
- 客户端生成的随机数,稍后用于生成“对话密钥”。
- 支持的加密算法,比如 RSA 公钥加密。
- 支持的压缩方法。
这里注意客户端发送的信息中不包含服务器的域名。也就是说理论上服务器只能包含一个网站,否则会分不清楚应该向客户端提供哪个网站的数字证书,这就是为什么通常一台服务器只能有一张数字证书发原因。
ServerHello
服务器响应信息:
- 确认使用的加密通信协议版本,比如 TLS 1.0。如果浏览器与服务器支持的版本不一致,则服务器关闭加密通信。
- 服务器生成的随机数,稍后用于生成“对话密钥”。
- 确认使用的加密方法,比如 RSA 公钥加密。
- 服务器证书。
- 客户端证书请求(如果服务器需要确认客户端的身份,如金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供 USB 密钥,里边就包含一张客户端证书)。
客户端回应
客户收到服务器回应后,首先验证服务器证书。如果证书不是可信的 CA 机构颁布或者证书中的域名与实际域名不一致或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。
如果证书没有问题,客户端就会从证书中取出服务器的公钥,然后向服务器发送下面三项信息。
- 客户端生成的随机数。该随机数用服务器公钥加密,防止被窃听。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的 hash 值,用来供服务器检验。
- 客户端证书(如果前一步,服务器要求客户端证书)。
上面第一项的随机数是整个握手阶段出现的第三个随机数,又称“pre-master key”。所以客户端和服务端同时有了三个随机数,接着双方就用实现商定的加密方法,各自生成本次会话所用的同一把“会话密钥”。
为什么一定要用三个随机数来生成“会话密钥”?
pre master 的存在在于 SSL 协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么 pre master secret 就有可能被猜测出来,那么仅仅用 pre master secret 做为密钥就不和适了,因此必须引入新的随机因素。所以客户端和服务端加上 pre master secret 三个随机数一同生成的密钥就不容易被猜出来了,一个伪随机可能不完全随机,可是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。这里注意,因为第一个和第二个随机数都是明文传输的,如果客户端随机是一个伪随机,那么第三方通过第一个随机数猜出 pre master key 的几率就大大增加,所以用三个随机数混合加密出一个“会话密钥”。
服务器的最后回应
服务器收到客户端的第三个随机数 pre-master key 之后,计算生成本次会话所用的”会话密钥”。然后,向客户端最后发送下面信息:
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的 hash 值,用来供客户端校验。
至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用”会话密钥”加密内容。
39. JWT 认证机制?
40. 正向代理与反向代理?
正向代理是从客户端的角度出发,服务于特定用户(比如说一个局域网内的客户)以访问非特定的服务;反向代理正好与此相反,从服务端的角度出发,服务于非特定用户(通常是所有用户),已访问特定的服务。
正向代理(forward proxy),一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并制定目标(原始服务器),然后代理向原始服务器转发请求并将获得的内容返回给客户端,客户端才能使用正向代理。我们平时说的代理就是指正向代理。
简单一点:A 向 C 借钱,由于一些情况不能直接向 C 借钱,于是 A 想了一个办法,他让 B 去向 C 借钱,这样 B 就代替 A 向 C 借钱,A 就得到了 C 的钱,C 并不知道 A 的存在,B 就充当了 A 的代理人的角色。
反向代理(Reverse Proxy),以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求的客户端,此时代理服务器对外表现为一个反向代理服务器。
理解起来有些抽象,可以这么说:A 向 B 借钱,B 没有拿自己的钱,而是悄悄地向 C 借钱,拿到钱之后再交给 A,A 以为是 B 的钱,他并不知道 C 的存在。
正向代理和反向代理的区别?
位置不同
正向代理,架设在客户机和目标主机之间;
反向代理,架设在服务器端;
代理对象不同
正向代理,代理客户端,服务端不知道实际发起请求的客户端;
反向代理,代理服务端,客户端不知道实际提供服务的服务端;
用途不同
正向代理,为在防火墙内的局域网客户端提供访问 Internet 的途径;
反向代理,将防火墙后面的服务器提供给 Internet 访问;
安全性不同
正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此必须采取安全措施以确保仅为授权的客户端提供服务;
反向代理都对外都是透明的,访问者并不知道自己访问的是哪一个代理。
正向代理的应用
- 访问原来无法访问的资源
- 用作缓存,加速访问速度
- 对客户端访问授权,上网进行认证
- 代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
反向代理的应用
- 保护内网安全
- 负载均衡
- 缓存,减少服务器的压力
41. CDN 原理?
CDN 是将源站内容分发至全国所有的节点,从而缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性的技术。它能够有效解决网络带宽小、用户访问量大、网点分布不均等问题。
- 用户访问图片内容,先经过本地 DNS 解析,如果命中,直接返回给用户。
- 没命中,转发授权 DNS 查询。
- 返回域名 CNAME 对应 IP 地址(实际就是 DNS 调度系统的 ip 地址)。
- 域名解析请求发送至 DNS 调度系统,DNS 调度系统为请求分配最佳节点 IP 地址。
- 返回的解析 IP 地址。
- 用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传送到用户终端。
如果不明白可以看看下图:
CDN 的组成
全局负载均衡系统 GLB(Global Load Balance)
- 当用户访问加入 CDN 服务的网站时,域名解析请求将最终由 “智能调度 DNS”负责处理。
- 它通过一组预先定义好的策略,将当时最接近用户的节点地址提供给用户,使用户可以得到快速的服务。
- 同时它需要与分布在各地的 CDN 节点保持通信,跟踪各节点的健康状态、容量等信息,确保将用户的请求分配到就近可用的节点上。
CDN 调度策略
DNS 调度
基于请求端 local DNS 的出口 IP 归属地以及运营商的 DNS 调度。
DNS 调度的问题:
- DNS 缓存时间在 TTL 过期前是不会刷新的, 这样会导致节点异常的时候自动调度延时很大,会直接影响线上业务访问。
- 大量的 local DNS 不支持 EDNS 协议,拿不到客户的真实 IP,CDN 绝大多数时候只能通过 local DNS IP 来做决策,经常会出现跨区域调度的情况。
HTTP DNS 调度
客户端请求固定的 HTTP DNS 地址,根据返回获取解析结果。可以提高解析的准确性(不像 DNS 调度,只能通过 local DNS IP 来做决策),能很好的避免劫持等问题。
当然这种模式也有一些问题,例如客户端每次加载 URL 都可能产生一次 HTTP DNS 查询,这就对性能和网络接入要求很高。
302 调度
基于客户端 IP 和 302 调度集群进行实时的流量调度。
我们来看一个例子:
- 访问 URL 链接后,此时请求到了调度群集上,我们能拿到的客户端信息有 客户端的出口 IP(绝大多情况下是相同的),接下来算法和基于 DNS 的调度可以是一样的,只是判断依据由 local DNS 出口 ip 变成了客户端的出口 IP。
- 浏览器收到 302 回应,跟随 Location 中的 URL,继续发起 http 请求,这次请求的目标 IP 是 CDN 边缘节点,CDN 节点会响应实际的文件内容。
302 调度的优势:
- 实时调度,因为没有 local DNS 缓存的,适合 CDN 的削峰处理,对于成本控制意义重大;
- 准确性高,直接获取客户端出口 IP 进行调度。
302 调度的劣势:
每次都要跳转,对于延时敏感的业务不友好。一般只适用于大文件。
42. OSI 七层网络模型,每一层有什么作用?
- 应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet。
- 表示层 数据格式化,代码转换,数据加密 没有协议。
- 会话层 解除或建立与别的接点的联系 没有协议。
- 传输层 提供端对端的接口 TCP,UDP。
- 网络层 为数据包选择路由 IP,ICMP,RIP,OSPF,BGP,IGMP。
- 数据链路层 传输有地址的帧以及错误检测功能 SLIP,CSLIP,PPP,ARP,RARP,MTU。
- 物理层 以二进制数据形式在物理媒体上传输数据 ISO2110,IEEE802,IEEE802.2。
43. TCP/IP 五层模型,各层对应哪些设备?
物理层:中继器、集线器、还有我们通常说的双绞线也工作在物理层。
数据链路层:网桥(现已很少使用)、以太网交换机(二层交换机)、网卡(其实网卡是一半工作在物理层、一半工作在数据链路层)。
网络层:路由器、三层交换机。
传输层:四层交换机、也有工作在四层的路由器。
44. 怎么设计让 udp 保证可靠性?
UDP 面向无连接,因此无法保证可靠性传输,只能通过应用层来实现了。在应用层来实现确认机制、重传机制、窗口确认机制。实际上就是把 TCP 所做的转移到了应用层。
目前有如下开源程序利用 UDP 实现了可靠的数据传输。分别为 RUDP、RTP、UDT。
可以使用 UDT,UDT 是基于 UDP 的可靠数据传输协议。
UDT 是双工的,每个 UDT 实体有两个部分:发送和接收。发送者根据流量控制和速率控制来发送(和重传)应用程序数据。接收者接收数据包和控制包,并根据接收到的包发送控制包。发送和接收程序共享同一个 UDP 端口来发送和接收。
接收者也负责触发和处理所有的控制事件,包括拥塞控制和可靠性控制和他们的相对机制,例如 RTT 估计、带宽估计、应答和重传。
UDT 总是试着将应用层数据打包成固定的大小,除非数据不够这么大。和 TCP 相似的是,这个固定的包大小叫做 MSS(最大包大小)。由于期望 UDT 用来传输大块数据流,我们假定只有很小的一部分不规则的大小的包在 UDT session 中。MSS 可以通过应用程序来安装,MTU 是其最优值(包括所有包头)。
UDT 拥塞控制算法将速率控制和窗口(流量控制)合并起来,前者调整包的发送周期,后者限制最大的位被应答的包。在速率控制中使用的参数通过带宽估计技术来更新,它继承来自基于接收的包方法。同时,速率控制周期是估计 RTT 的常量,流控制参数依赖于对方的数据到达速度,另外接收端释放的缓冲区的大小。
45. 介绍下 HTTP 中间人攻击?
中间人攻击过程如下:
- 服务器向客户端发送公钥。
- 攻击者截获公钥,保留在自己手上。
- 然后攻击者自己生成一个【伪造的】公钥,发给客户端。
- 客户端收到伪造的公钥后,生成加密 hash 值发给服务器。
- 攻击者获得加密 hash 值,用自己的私钥解密获得真秘钥。
- 同时生成假的加密 hash 值,发给服务器。
- 服务器用私钥解密获得假秘钥。
- 服务器用加秘钥加密传输信息
46. 请求头 Access-Control-Request-Method 是什么?
请求头 Access-Control-Request-Method
出现于 preflight request
(预检请求)中,用于通知服务器在真正的请求中会采用哪种 HTTP 方法。因为预检请求所使用的方法总是 OPTIONS
,与实际请求所使用的方法不一样,所以这个请求头是必要的。
47. 正向代理、反向代理原理?
正向代理:VPN 就属于正向代理,我们将请求发送给代理服务器,代理服务器去访问国外的网站,然后将访问到的数据传递给我们!正向代理最大的特点是客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息。
反向代理:反向代理可以简单的理解为是对大哥的一种保护,由于真实的服务器在网络中一旦受到攻击就会带来数据丢失和被窃取的巨大风险,所以在互联网这个大环境中软件工程所要解决的一个问题就是对于真是服务器的保护--- 反向代理服务器,它的原理是隐藏真实服务器。
48. http1.1 和 http2.0 的区别?
- http1.x 的解析是基于文本协议的各式解析,而 http2.0 的协议解析是二进制格式,更加的强大。
- 多路复用(Mutiplexing) : 一个连接上可以有多个 request,且可以随机的混在一起,每个不同的 request 都有对应的 id,服务端可以通过 request_id 来辨别,大大加快了传输速率。
- header 压缩: http1.x 中的 header 需要携带大量信息。而且每次都要重复发送。http2.0 使用 encode 来减少传输的 header 大小。而且客户端和服务端可以各自缓存(cache)一份 header filed 表,避免了 header 的重复传输,还可以减少传输的大小。
- 服务端推送(server push): 可以通过解析 html 中的依赖,只能的返回所需的其他文件(css 或者 js 等),而不用再发起一次请求。
49. 怎么理解端到端的连接?
端到端是传输层的,你比如你要将数据从 A 传送到 E,中间可能经过 A→B→C→D→E,对于传输层来说他并不知道 b,c,d 的存在,他只认为我的报文数据是从 a 直接到 e 的,这就叫做端到端。 TCP 就是用来建立这种端到端连接的一个具体协议。
50. TCP 是怎么判断丢包的?
51. TCP 头部大小是固定的吗?
不是,TCP 头部的最后一个选项字段(options)是可变长的可选信息。这部分最多包含 40 字节,因为 TCP 头部最长是 60 字节(其中还包含前面讨论的 20 字节的固定部分)。
52. 应用层都有哪些协议?
- DNS:域名系统
- FTP:文件传输协议
- Telnet:远程终端协议
- HTTP:超文本传送协议
- SMTP:电子邮件协议
- POP3:邮件读取协议
- SNMP:简单网络管理协议
- TFTP:简单文件传送协议
53. http1.0 与 http1.1 之间的区别?
缓存策略
http1.0 的缓存策略主要是依赖 header 中的 If-Modified-Since
、Expire
(到期)
http1.1 的缓存策略要比 http1.0 略多,例如 Entity tag
(实体标签)、If-Unmodified-Since
、If-Match
、If-None-Match
等。
宽带和网络连接优化
http1.0 中会存在一些性能浪费,比如我们的只需要对象中的一部分,但是每次请求返回的却是整个对象,这无疑造成了性能的损害。
http1.1 则不然,它可以通过在请求头处设置 range
头域,就可以返回请求资源的某一部分,也就是返回码为 206(Partial Content)的时候,这对于性能优化很有必要。
关于断点续传的应用场景,例如用户需要下载一个大文件,最佳的方式是将这个大文件分割成几部分,然后由多个进程同时进行。这个时候,我们可以在请求头中设置 range
字段,来规定分割的 byte 数范围。而服务端会给客户端返回一个包含着 content-range
的响应头,来对应相应的分割 byte 数范围。
新增部分错误通知
http1.1 版本新增了 24 个错误状态响应码,比如:
409(Conflict)表示: 请求的资源与当前的状态发生冲突
410(Gone)表示服务器上某个资源被永久性的删除了
Host 头处理
http1.0 中默认每台服务器都绑定唯一的一个 IP 地址,所以请求消息中 url 并没有传递主机名,也就是 hostname。
http1.1 中请求消息和响应消息都支持 Host 头域,而且,如果我们不传这个字段还会报一个 400(bad request)的状态码。
长连接
http1.1 支持长连接和请求的流水线(pipelining),在一个 TCP 链接上可以传送多个 http 请求和响应,这样就不用多次建立和关闭 TCP 连接了。
54. TCP 如何保证数据包传输的有序可靠?
对字节流分段并进行编号然后通过 ACK 回复和超时重发这两个机制来保证。
- 为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区;
- 并为每个已发送的数据包启动一个超时定时器;
- 如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区;
- 否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
- 接收方收到数据包后,先进行 CRC 校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。
55. http 和 https 的区别及优缺点?
- http 是超文本传输协议,信息是明文传输,https 协议要比 http 协议安全,https 是具有安全性的 ssl 加密传输协议,可防止数据在传输过程中被窃取、改变,确保数据的完整性(当然这种安全性并非绝对的,对于更深入的 Web 安全问题,此处暂且不表)。
- http 协议的默认端口为 80,https 的默认端口为 443。
- http 的连接很简单,是无状态的。https 握手阶段比较费时,会使页面加载时间延长 50%,增加 10%~20% 的耗电。
- https 缓存不如 http 高效,会增加数据开销。
- https 协议需要 ca 证书,费用较高,功能越强大的证书费用越高。
- SSL 证书需要绑定 IP,不能再同一个 IP 上绑定多个域名,IPV4 资源支持不了这种消耗。
56. 什么是 TCP 粘包?
多个数据包被连续存储于连续的缓存中,在对数据包进行读取时由于无法确定发生方的发送边界,而采用某一估测值大小来进行数据读出,若双方的 size 不一致时就会使指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
发送方引起的粘包是由 TCP 协议本身造成的,TCP 为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常 TCP 会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。
接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。
粘包的处理方式:
- 当时短连接的情况下,不用考虑粘包的情况。
- 如果发送数据无结构,如文件传输,这样发送方只管发送,接收方只管接收存储就 ok,也不用考虑粘包。
- 如果双方建立长连接,需要在连接后一段时间内发送不同结构数据。
接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开。实验证明这种方法是高效可行的。
57. Content-Encoding 有几种?
Content-Encoding
实体头用于压缩媒体类型。如果存在,它的值表示哪些编码应用于实体主体。它让客户知道,如何解码以获取。
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
Content-Encoding: identity
Content-Encoding: br
# Multiple, in the order in which they were applied
Content-Encoding: gzip, identity
Content-Encoding: deflate, gzip
gzip:一种使用 Lempel-Ziv 编码( LZ77 )和 32 位 CRC 的格式。这最初是 UNIX gzip 程序的格式。
x-gzip:为了兼容性的目的,HTTP / 1.1 标准还建议支持该内容编码的服务器应该将其识别为别名。
compress:使用 Lempel-Ziv-Welch( LZW )算法的格式。值名取自实施此算法的 UNIX 压缩程序。
与大多数 UNIX 发行版已经消失的压缩程序一样,目前几乎没有浏览器使用这种内容编码,部分原因是由于专利问题(已在 2003 年过期)。
deflate:使用 deflate 压缩算法(在 RFC 1951 中定义)使用 zlib 结构(在 RFC 1950 中定义)。
identity:指示身份功能(即不压缩,也不修改)。除非明确指定,否则此标记始终被视为可接受。
br:使用 Brotli 算法的格式。