Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

计算机网络、性能优化、安全、浏览器 #22

Open
L-small opened this issue May 6, 2020 · 0 comments
Open

计算机网络、性能优化、安全、浏览器 #22

L-small opened this issue May 6, 2020 · 0 comments

Comments

@L-small
Copy link
Owner

L-small commented May 6, 2020

进程和线程

进程是资源分配的最小单位,进程是程序的运行实例。进程中使用多线程并行处理可以提升运算效率。
线程是CPU调度的最小单位。不能单独存在,由进程来启动和管理,一个进程可以有多个线程。

三次握手

  • 客户端发送SYN=1报文和序列号seq=x
  • 服务端接收并返回确认报文段SYN=1,ACK=1,初始序列seq=y,确认号ack=x+1
  • 客户端返回报文段ACK=1 序号seq=x+1 确认号ack=y+1(可携带数据)
    image

ISN不是固定的,是动态生成的

第三次握手可携带数据

第三次已经建立了连接了,第一次不行是容易收到攻击

SYN攻击

服务器端资源分配是在二次握手时分配的,客户端的资源是在完成三次握手分配的。客户端伪造大量IP地址对服务器发送SYN包。当发现有大量随机IP地址并且是半连接状态则是。

解决方法:

  • 过滤网关保护
  • 缩短超时时间
  • 增加最大半连接数

四次挥手

  • 客户端发出fin
  • 服务端接收发送ack
  • 服务端发送fin
  • 客户端发出ack
    image

为什么挥手需要4次

因为ACK是用来应答的、SYN用来同步的,当收到服务端的FIN时,则只是关闭了连接,先回复个ACK收到了,等待其他任务执行完确认关闭了在发送FIN报文

2MSL连接意义

如果挥手时,客户端发送的ACK丢了,不等待的话,服务器收不到ACK则一直在等待不能关闭,后面再重新发送FIN,客户端已经关闭了所以收不到。服务器陷入不能关闭的地步

为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态

网络不可靠,这段时间就是用来重发可能丢失的ACK报文

五层网络

  • 应用层 HTTP
  • 传输层 TCP UDP 端口
  • 网络层 IP协议、DNS协议
  • 数据链路层 Mac地址、以太网
  • 物理层

TLS

  • 客户端发送加密算法、协议版本、本地随机数
  • 服务端确认加密方法,给出数字证书,服务器生成随机数
  • 服务端发送数字证书(有公钥),加密算法
  • 客户端确认证书,使用公钥加密,新生成随机数
  • 服务端用私钥获取随机数
  • 使用前面的三个随机数生成对话密钥,加密后面的对话

状态码

  • 2XX 请求成功
    • 204 请求成功,但是没有内容返回
    • 206 请求资源一部分,content-range指定内容
  • 3XX 重定向代码
    • 301 永久重定向
    • 302 临时重定向
    • 303 临时重定向,但是只能用Get请求
    • 304 资源找到了,但不符合条件请求,比如If-Match等
    • 307 临时重定向,不会把post变成get
  • 4XX 客户端错误状态码
    • 400 请求报文存在语法问题
    • 401 该请求,需要通过HTTP等认证。初次返回认证,第二次则是认证失败
    • 403 请求资源的访问被服务器拒绝了
    • 404 服务端拒绝请求且不说明理由,服务器上无法找到资源
    • 405 方法不被允许
  • 5XX 服务器错误
    • 500 服务器报错
    • 502 从上游网关和代理角色的服务器传来的无效,一般nginx报错
    • 503 服务器正忙,或者无服务

首屏加载优化

  • Vue-router的懒加载
  • 使用CDN
  • Nginx的gzip压缩
  • Vue异步组件、按需加载
  • 服务端渲染
  • webpack开启gzip压缩
  • service worker缓存文件处理
  • link标签添加prefetch、preload优先下载
  • 骨架屏

HTTP1.0-3.0

HTTP1.0

默认是短连接,每次和服务器通信都要建立链接。

HTTP1.1

默认是持久化链接。引入范围请求,实现断点续传。并可以同时发送多个请求

HTTP2.0

多路复用技术(一个TCP链接中可以有多个数据流),同时发起多次请求。头部压缩(只发送改动的头)。服务器推送。二进制分帧(解决队首阻塞)

HTTP3.0

集成了TLS加密,改进拥塞控制、快速握手(基于UDP)、连接迁移(只通过conection ID,id不变链接不需要重新建立)

Service Worker

  • 缓存静态资源
  • 离线缓存,接口,文件等
  • push推送

同源策略

同源策略:端口、域名、协议相同

主要表现在DOM、Web数据、网络三个层面

  • DOM,限制不同源的JS脚本对当前DOM对象的读和写。同源下通过opener.document可以访问上一个同源页面的DOM
  • 数据层面。限制不同源站点读取当前站点的Cookie、IndexDB、LocalStorage等数据。
  • 网络层面。通过XMLHttpRequest等方式将站点的数据发送给不同源的站点。

XSS

跨站脚本攻击,在代码中加入<script>xxx</script>来进行一些操作。

主要分为:

  • 存储型:将恶意代码会存储到数据库,比如创建专辑名<script>xxx</script>,当别人访问的时候就会执行
  • 反射型:不存储到数据库,比如一些请求的参数修改为恶意代码,然后服务器又将参数返回执行
  • DOM型:在Web传输的过程中修改html内容等,比如网页劫持的弹窗广告

处理方式:

  • 输入检查。对用户的输入进行转义,检查,过滤
  • httpOnly。服务器将HTTP响应头的Cookie设置为httpOnly标志。标记只能由http请求访问,JS不能访问。
  • CSP。Content-Security-Policy: 策略,比如default-src 'self' *.trusted.com(一个网站管理者允许内容来自信任的域名及其子域名)

其他:Vue因为在编译的时候所有的都是以字符串的形式处理的,并且他会匹配是否有script标签,然后此时是不允许执行的,并给提示

CSRF

跨站请求伪造,主要针对服务器的漏洞。

处理方法:

  • Cookie的SameSite属性。设置为Strict或者Lax
  • 验证请求的来源站点。通过http请求的reference来验证请求来源(不太可靠,可设置传或不传。有域名、路径及参数信息)。通过Origin属性(只包含域名信息)
  • CSRF Token。浏览器向服务端发起请求的时候生成一个CSRF Token注入页面,然后浏览器再次发起请求,会带上这个,然后服务端验证是否合法。

浏览器渲染

渲染的处理流程我们一般称为渲染流水线

主要分为以下:

  • 构建DOM树
  • 样式计算
  • 布局
  • 分层
  • 绘制
  • 分块
  • 光栅化
  • 合成

构建DOM树

输入:HTML

因为浏览器不能直接理解和使用HTML,所以需要将HTML转为浏览器可以理解的DOM树。(document输出的就是DOM树)一个树形结构的(有点像虚拟DOM)。

输出:DOM树

样式计算

计算出DOM的具体样式

输入:CSS

流程
1、把CSS转换成浏览器可理解的结构styleSheets。该结构具备查询和修改功能
2、转换样式表中的属性值,使其标准化。将blue、em等转换为rgba和px
3、计算DOM树中每个节点的具体样式。用到CSS的继承规则和层叠规则

输出:styleSheets

布局

输入:DOM树和styleSheets

流程:

  • 通过DOM树和styleSheets生成一个只包含可见元素的布局树。浏览器遍历DOM树将所有可见节点添加到布局树中
  • 布局计算。元素的位置

输出:布局树

分层

输入:布局树

生成图层树。为应对z-index、页面滚动、3D变化等,进行分层。渲染引擎还为特定的节点生成专用的图层,并生成一个图层树。

页面由图层叠加后呈现的。不是布局树每个节点都有一个图层,节点没有对应的层就继承父节点的层。

提升为单独一个图层的条件:

  • 拥有层叠上下文的属性的元素,比如z-index、fixed、opacity等
  • 需要裁剪的地方,比如设定了宽高的div,但是文字盛不下。

输出: 图层树

图层绘制

输入:图层树

把图层树进行绘制。将一个图层的绘制分成很多小的绘制指令,然后按照这些指令顺序组成一个待绘制的列表

输出:绘制列表

栅格化

输入:绘制列表

将绘制列表提交给合成线程。合成线程将图层划分为图块(256256或者512512)。优先将视口附近的图块优先生成位图。

一般栅格化过程会用GPU加速生成,用GPU生成位图的过程称为快速栅格化,生成的位图保存在GPU内存中。
image

输出:位图

合成和显示

所有图块都被光栅化后,合成线程生成一个绘制图块的指令,提交给浏览器进程,浏览器进程收到后则根据命令将页面绘制到内存中,最后显示在屏幕上

其他

如果下载CSS文件阻塞了,会阻塞DOM树合成么?会阻塞页面显示么?

当浏览器接收到HTML时,DOM解析器开始工作,解析过程中遇到JS脚本

  • 内联脚本:<script>xxx</script>类型的则先执行JS,执行完后再继续往下解析
  • 外部JS:先暂停DOM解析,下载完成后执行JS,然后继续往下解析DOM
  • 碰到CSS时,先下载完成后再继续DOM解析,所以会阻塞DOM解析

重排

更新了元素的几何属性。比如宽度、高度触发重新布局,然后执行后面的一系列阶段,需要更新完整的渲染流水线,所以开销最大
image

重绘

更改了元素的绘制属性。比如修改背景色等。由于没有更改布局,所以直接进入绘制阶段和后面的子阶段。省去了布局和分层,比重排效率要高。
image

直接合成

使用CSS的transform实现动画效果,避开重绘和重排,在非主线程上合成动画操作,效率最高。避开了布局和绘制。
image

浏览器缓存

缓存可以分为:强缓存和协商缓存。协商缓存依赖强缓存,没有强缓存就没有本地缓存。

强缓存:

通过控制台可以看到,http状态为200,size显示from cache的请求是命中了强缓存的请求。

强缓存主要是Expires或者Cache-Control这两个response header实现的,他们都是表示资源在客户端缓存的有效期,Cache-Control的优先级高于Expires,两个header可同时存在

1) Expires

是http1.0提出的一个表示资源过期时间的header,过期时间是一个绝对时间,用GMT格式字符串表示,如:Expires:Thu, 31 Dec 2037 23:55:55 GMT

  • 过程:

(1)浏览器第一次向服务器请求一个资源,服务器在返回这个资源的同时,在response header上加上Expires的header

(2)浏览器接收到这个资源的时候,会把这个资源连同所有response header一起缓存下来

(3)浏览器再次请求这个资源时,先从缓存中查找这个资源,找到后再和它的Expires跟当前本地时间作比较,如果在Expires指定时间前,则命中缓存

(4)如果没命中缓存,则请求服务器获取资源,并更新Expires Header

  • 缺点:由于Expires返回的是一个绝对时间,修改本地时间会影响缓存命中的结果。

2) Cache-Control

是http1.1提出的一个表示资源过期时间的header,过期时间是一个相对时间,以秒为单位,用数值表示,如:Cache-Control:max-age=315360000。

Cache-Control还有其他的值:

1、 no-store:不缓存
2、 no-catch:缓存前,向服务器进行新鲜度验证
3、 public:可以被所有用户缓存
4、 private:不允许中继服务器缓存,只能被终端浏览器缓存

  • 过程:

(1)浏览器第一次向服务器请求一个资源,服务器在返回这个资源的同时,在response header上加上Cache-Control的header

(2)浏览器接收到这个资源的时候,会把这个资源连同所有response header一起缓存下来

(3)浏览器再次请求这个资源时,先从缓存中查找这个资源,找到后再通过第一次请求时间和Cache-Control设定的有效期计算出资源过期时间,这个时间跟当前本地时间作比较,如果在过期时间前,则命中缓存

(4)如果没命中缓存,则请求服务器获取资源,并更新Cache-Control Header


协商缓存

http状态码是304,并显示Not Modified,则是命中了协商缓存

协商缓存主要是通过[Last-Modified,If-Modified-Since]和[ETag,If-None-Match]这两对header来管理

1) [Last-Modified,If-Modified-Since]

  • 过程:

(1)浏览器第一次向服务器请求一个资源,服务器在返回这个资源的同时,在response header里加上Last-Modified,这个表示这个资源在服务器上最后的修改时间

(2)浏览器再次向服务器请求这个资源时,在request header上加上If-Modified-Since,这个值就是上次请求response的Last-Modified的值

(3)服务器收到请求时,根据传过来的If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,如果没有变化则返回304 Not Modified,但是服务器不会返回资源内容。当返回了304 Not Modified时,response中不会再添加Last-Modified,因为资源没有变化,Last-Modified也不会变化

(4)浏览器收到304响应后,从浏览器缓存中加载资源

(5)如果协商缓存没有命中,则从服务器中加载资源,Last-Modified在重新加载的时候会更新,并通过response header返回回去

  • 缺点:一般很可靠,但是也会有服务器资源发生变化,但是最后修改时间却没有变化的情况

2) [ETag,If-None-Match]

  • 过程:

(1)浏览器第一次请求服务器资源时,服务器返回资源的同时,在response header里加上ETag,这个值是当前资源的唯一的标识,只要资源有变化,ETag就会变化

(2)浏览器再次请求这个资源的时候,在request header上加上If-None-Match,这个值就是上次请求返回的ETag的值

(3)服务器收到资源请求时,服务器会再生成一个新的ETag和传来的If-None-Match作比较,如果相同则命中缓存,返回304 Not Modified,不返回资源内容,并将ETag返回回去,即使没有变化。如果不相同,则返回资源内容。


浏览器行为对缓存的影响

缓存的处理方式可以被浏览器的行为改变,比如:

ctrl+f5强制刷新页面的时候,直接请求源服务器,跳过协商缓存和强缓存

f5刷新的时候,跳过强缓存,检查协商缓存

amandakelake/blog#41
http://www.cnblogs.com/lyzg/p/5125934.html?f=tt

cookie和session区别

session:在服务端。被默认放在一个文件中,保存方式有很多(内存、数据库、文件)。依赖session_id,这个又放在cookie中,cookie禁用了session也失效了,当然也可以通过url传递
cookie:在客户端保存用户信息的一种机制。

跨域

三个允许跨域的标签

<img src=XXX>
<link href=XXX>
<script src=XXX>

JSONP

原理:利用script标签没有跨域限制,可以从其他来源获取json数据

优点:简单,兼容性好
缺点:只能Get请求,容易XSS

实现:

  • 声明一个回调函数,函数名当做参数
  • 创建一个script标签,把请求地址+函数名传入
  • 服务端接受后,处理请求,把函数名和数据拼接成字符串
  • 服务器传回请求,客户端执行回调函数

CORS

实现:Access-Control-Allow-Origin 设置相应的域名

处理:

  • 简单请求:
    • GET、POST、HEAD
    • text/plain、multipart/form-data、application/x-www-form-urlencoded三种格式
  • 复杂请求:
    • 增加一次options预检查请求、来判断服务端是否支持跨域请求

服务器代理。服务器端没有跨域限制,则同源服务器处理跨域请求

postMessage 不同源的脚本采用异步的方式跨文本和窗口的有限通信

websocket

nginx反向代理

window.name + iframe。name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值

location.hash + iframe

document.domain + iframe

https

https是在http上建立SSL加密层,http协议是http直接请求TCP,https是http先请求TLS/SSL,然后请求TCP,对传输数据进行加密

优点:

  • 数据隐私性:内容经过对称加密,每个链接生成唯一的加密秘钥
  • 数据完整性:内容传输经过完整性校验
  • 身份认证:第三方无法伪造身份

缺点:

  • 增加加密解密流程,有消耗

流程:
image

  • 客户端发起https请求,请求443端口
  • 服务端把公钥证书返回给客户端
  • 客户端验证公钥证书,通过后用伪随机数生成器生成加密所使用的对称密钥,用证书的公钥加密这个对称密钥,传给服务端
  • 服务端用私钥解密得到对称密钥,服务端用对称密钥加密明文A发给客户端
  • 客户端用对称密钥解密得到明文A
  • 客户端再次发起请求,通过对称密钥加密明文B,服务端接收到,并用对称密钥解密得到明文B

输入URL后的过程

  • 浏览器阶段
    • UI线程处理,进行URL解析
    • DNS解析(先查浏览器缓存 -> 本地DNS解析器缓存 -> 路由器缓存 -> 本地DNS服务器 -> 根DNS服务器)。可以DNS-prefetch预解析提高DNS解析速度(DNS劫持:修改假的映射IP地址)
    • 通知网络线程,初始化一个网络请求
    • 查看缓存。此处可service-worker离线缓存请求
  • 网络阶段
    • 建立链接。应用层发送HTTP请求、表示层建立TLS链接、传输层建立TCP链接(SYN攻击)、网络层IP协议找到Mac地址、数据链路层以太网协议
    • Nginx接收转发
    • 处理请求(如果重定向,浏览器需要再发一次请求)
    • 服务器接收响应,返回请求
  • 重回浏览器阶段
    • 网络进程接收到http的主体流,并检查流前几个字节确定类型,或者通过content-type,失误或缺失下用MIME类型嗅探确定媒体类型
    • 安全检查。是否与已知病毒网站匹配,展示警告页
    • CROB检查敏感跨站去请数据(会进行CPU预执行文件内容,而不是到渲染阶段)
    • 转到了渲染进程(在发送请求时就提前初始化了一个渲染进程,节省时间)
    • 构建DOM树,通过preload预加载资源、sciprt加async(乱序)和defer(顺序,执行时不影响页面构建) 字节流解码->输入流预处理->token化->构建树->DOM
    • 样式计算styleSheets
    • 生成布局树
    • 分层
    • 绘制
    • 分块
    • 光栅化
    • 合成

事件机制

  • 接受各类输入事件
  • 浏览器进程将事件类型和坐标发送给渲染进程
  • 渲染进程寻找事件目标对象并执行回调
  • 合成线程接受输入事件
  • 非快速滚动区域(用户事件发生在此区域、进行命中测试,通过绘画记录找到时间目标对象)
  • 合成线程和主线程通信,并在每次输入事件进入时等待他,影响平滑滚动
  • 合并事件发给主线程
@L-small L-small changed the title 面试——网络协议 计算机网络 May 8, 2020
@L-small L-small changed the title 计算机网络 计算机网络、性能优化 May 22, 2020
@L-small L-small changed the title 计算机网络、性能优化 计算机网络、性能优化、安全 May 23, 2020
@L-small L-small changed the title 计算机网络、性能优化、安全 计算机网络、性能优化、安全、浏览器 May 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant