计算机基础笔记
计算机基础笔记
野菜一、 跨域问题
概述:浏览器基于安全因素的考虑,是不允许进行跨域请求的,如果发生跨域请求,就会发生一下类似的错误。
跨域原因:
- 协议:
http - 域名:
baidu.com - 端口号:
3000
解决:解决方案有很多种,比如前端开发时进行反向代理,使用JSONP,后端设置CORS、配置 nginx 反向代理等等
1. CORS
概述:跨域资源共享是一种机制,当一个资源访问到另一个资源时,资源就会发起一个跨域的http请求需要浏览器和服务器同时支持:
node.js处理
1 | app.use('*', function(req, res, next) { |
2. 反向代理
- Vue config.js中配置
1 | devServer: { |
- React 在src目录下创建setupProxy.js文件
- 下载依赖
1 | npm i http-proxy-middleware -D |
1 | const {createProxyMiddleware} = require('http-proxy-middleware') |
3. Nginx
二、HTTP问题
原理:HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
步骤:客户端连接到Web服务器->发送Http请求->服务器接受请求并返回HTTP响应->释放连接TCP连接->客户端浏览器解析HTML内容
2.1 GET和POST请求
- 应用场景:GET请求用于对服务器资源不会产生影响的场景。而POST请求一般用于对服务器资源会产生影响的场景。
- 是否缓存:浏览器一般会对GET请求进行缓存,但很少对POST请求进行缓存。
- 请求参数:GET请求使用URL进行传递参数,URL的?后面拼接参数,POST请求中的实体报文部分一般为服务器发送的数据。
- 安全性:因为GET请求的参数是拼接在URL后面的,所以安全性较差,因为请求的URL会被保留在历史记录中,而POST请求安全性较好。
- 请求长度:浏览器对URL有长度限制,因此会影响GET请求发送数据的长度,而POST请求并没有长度限制。
- 刷新:GET请求支持刷新和后退,而POST请求每次刷新都会重新发送
- 参数类型:POST请求的参数传递支持更多的数据类型
2.2 HTTP请求头和响应头
请求头:
- Accept:浏览器能够处理的内容类型
- Accept-Charset:浏览器能够显示的字符集
- Accept-Encoding:浏览器能够处理的压缩编码
- Accept-Language:浏览器当前设置的语言
- Connection:浏览器与服务器之间连接的类型
- Cookie:当前页面设置的任何Cookie
- Host:发出请求的页面所在的域
- Referer:发出请求的页面的URL
- User-Agent:浏览器的用户代理字符串
响应头:
- Date:表示消息发送的时间,时间的描述格式由rfc822定义
- server:服务器名称
- Connection:浏览器与服务器之间连接的类型
- Cache-Control:控制HTTP缓存
- content-type:表示后面的文档属于什么MIME类型
2.3 HTTP状态码304
概述:客户端有缓存情况下的服务端的一种响应客户端性能优化的一种方式
过多的304状态码可能会导致网站快照停止,收录减少,权重下降
2.4HTTP 1.0 和 HTTP 1.1
- 连接方面:1.0默认使用非持久连接,而1.1 默认使用持久连接。1.1通过使用持久连接来使多个http请求复用同一个TCP连接,一次来避免使用非持久连接时每件需要建立链接的时延。
- 资源请求:1.0 中会存在一些浪费宽带的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。1.1 则在请求头引入 range 头域,他允许只请资源的某个部分,即返回码是206
- 缓存方面: 1.0 主要使用了 header 里的 If-Modified-Since、Expires 来做为缓存判断的标准,http1.1 则引入了更多的缓存控制策略,例如 Etag、If-Unmodified-Since、If-Match、If-None-Match 等更多可供选择的缓存头来控制缓存策略
- 1.1 新增加了 host 字段,用来指定服务器的域名。1.0 中并没有传递主机名。
- 1.1 新增加了很多的请求方法
2.5 HTTP 1.1 和 HTTP 2.0
- 二进制协议:1.1 中的豹纹的头信息必须是文本,数据体可以是文本,也可以是二进制。2.0 则是一个彻底的二进制协议,头信息和数据题都是二进制
- 多路复用:2.0 实现了多路复用,任然复用TCP连接,但是在一个连接里,客户端和服务器都可以同时发送多喝请求或者回应,而且不用按照顺序一一发送。
- 数据流:2.0使用了数据流的概念,因为2.0的数据包是不按顺序发送的,同一个链接里面连续的数据包,可能属于不同的请求。因此,必须对数据包做标记,指出他属于那个请求。2.0将每个请求或回应的所有数据包,成为一个数据流,每个数据流都有一个独一无二的编号。
- 头信息压缩: HTTP/2 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 Cookie 和 User Agent ,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了。
- 服务器推送: HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。使用服务器推送提前给客户端推送必要的资源,这样就可以相对减少一些延迟时间。这里需要注意的是 http2 下服务器主动推送的是静态资源,。
2.6 HTTP和HTTPS
- HTTPS 协议需要CA证书,费用较高;HTTP协议不需要
- HTTPS是超文本传输协议,信息是明文传输的;HTTPS则是具有安全性的SSL加密传输协议
- 使用不同的连接方式,端口也不同,HTTP协议端口是80,HTTPS协议端口是443
- HTTP协议连接很简单,是无状态的;HTTPS协议是由SSL和HTTP协议够贱的可进行加密传输,身份认证的网络协议,比HTTP更加安全。
2.7 输入URL后发生了生么
- )解析URL:首先会对 URL 进行解析,分析所需要使用的传输协议和请求的资源的路径。如果输入的 URL 中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。如果没有问题,浏览器会检查 URL 中是否出现了非法字符,如果存在非法字符,则对非法字符进行转义后再进行下一过程。
- 缓存判断:浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并且没有失效,那么就直接使用,否则向服务器发起新的请求。
- DNS解析:下一步首先需要获取的是输入的 URL 中的域名的 IP 地址,首先会判断本地是否有该域名的 IP 地址的缓存,如果有则使用,如果没有则向本地 DNS 服务器发起请求。本地 DNS 服务器也会先检查是否存在缓存,如果没有就会先向根域名服务器发起请求,获得负责的顶级域名服务器的地址后,再向顶级域名服务器请求,然后获得负责的权威域名服务器的地址后,再向权威域名服务器发起请求,最终获得域名的 IP 地址后,本地 DNS 服务器再将这个 IP 地址返回给请求的用户。用户向本地 DNS 服务器发起请求属于递归请求,本地 DNS 服务器向各级域名服务器发起请求属于迭代请求。
- 获取MAC地址:当浏览器得到 IP 地址后,数据传输还需要知道目的主机 MAC 地址,因为应用层下发数据给传输层,TCP 协议会指定源端口号和目的端口号,然后下发给网络层。网络层会将本机地址作为源地址,获取的 IP 地址作为目的地址。然后将下发给数据链路层,数据链路层的发送需要加入通信双方的 MAC 地址,本机的 MAC 地址作为源 MAC 地址,目的 MAC 地址需要分情况处理。通过将 IP 地址与本机的子网掩码相与,可以判断是否与请求主机在同一个子网里,如果在同一个子网里,可以使用 APR 协议获取到目的主机的 MAC 地址,如果不在一个子网里,那么请求应该转发给网关,由它代为转发,此时同样可以通过 ARP 协议来获取网关的 MAC 地址,此时目的主机的 MAC 地址应该为网关的地址。
- TCP三次握手:下面是 TCP 建立连接的三次握手的过程,首先客户端向服务器发送一个 SYN 连接请求报文段和一个随机序号,服务端接收到请求后向服务器端发送一个 SYN ACK报文段,确认连接请求,并且也向客户端发送一个随机序号。客户端接收服务器的确认应答后,进入连接建立的状态,同时向服务器也发送一个ACK 确认报文段,服务器端接收到确认后,也进入连接建立状态,此时双方的连接就建立起来了。
- HTTPS握手:如果使用的是 HTTPS 协议,在通信前还存在 TLS 的一个四次握手的过程。首先由客户端向服务器端发送使用的协议的版本号、一个随机数和可以使用的加密方法。服务器端收到后,确认加密的方法,也向客户端发送一个随机数和自己的数字证书。客户端收到后,首先检查数字证书是否有效,如果有效,则再生成一个随机数,并使用证书中的公钥对随机数加密,然后发送给服务器端,并且还会提供一个前面所有内容的 hash 值供服务器端检验。服务器端接收后,使用自己的私钥对数据解密,同时向客户端发送一个前面所有内容的 hash 值供客户端检验。这个时候双方都有了三个随机数,按照之前所约定的加密方法,使用这三个随机数生成一把秘钥,以后双方通信前,就使用这个秘钥对数据进行加密后再传输。
- 返回数据:当页面请求发送到服务器端后,服务器端会返回一个 html 文件作为响应,浏览器接收到响应后,开始对 html 文件进行解析,开始页面的渲染过程。
- 页面渲染:浏览器首先会根据 html 文件构建 DOM 树,根据解析到的 css 文件构建 CSSOM 树,如果遇到 script 标签,则判端是否含有 defer 或者 async 属性,要不然 script 的加载和执行会造成页面的渲染的阻塞。当 DOM 树和 CSSOM 树建立好后,根据它们来构建渲染树。渲染树构建好后,会根据渲染树来进行布局。布局完成后,最后使用浏览器的 UI 接口对页面进行绘制。这个时候整个页面就显示出来了。
- TCP四次挥手:最后一步是 TCP 断开连接的四次挥手过程。若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。但是因为 TCP 连接是双向的,所以服务端仍旧可以发送数据给客户端。服务端如果此时还有没发完的数据会继续发送,完毕后会向客户端发送连接释放请求,然后服务端便进入 LAST-ACK 状态。客户端收到释放请求后,向服务端发送确认应答,此时客户端进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有服务端的重发请求的话,就进入 CLOSED 状态。当服务端收到确认应答后,也便进入 CLOSED 状态。
2.8 请求报文
- 请求行: 请求⽅法字段、URL字段、HTTP协议版本字段。它们⽤空格分隔。例如,GET /index.html HTTP/1.1。
- 请求头部: 请求头部由关键字/值对组成,每⾏⼀对,关键字和值⽤英⽂冒号“:”分割
- User-Agent:产⽣请求的浏览器类型。
- Accept:客户端可识别的内容类型列表。
- Host:请求的主机名,允许多个域名同处⼀个IP地址,即虚拟主机。
- 空行
- 请求体:post put等请求携带的数据
2.9 响应报文
- 响应行: 由网络协议版本,状态码和状态码的原因短语组成,例如 HTTP/1.1 200 OK 。
- 响应头:响应部首组成
- 空行
- 响应体:服务器响应的数据
2.10 URL
- 协议:访问服务器获取资源时使用的协议
- 域名:资源服务器主机名或IP地址
- 端口:资源服务器监听的端口,不同的scheme有不同的默认端口(HTTP使用80作为默认端口)
- 路径:服务器上的资源路径。路径与服务器和scheme有关
- 文件名:打开的文件名称
- 参数:提供给服务器上的值
- 锚点:打开用户页面时滚动到该锚点位置
2.11 常见的状态码
- 2开头的表示成功
- 一般见到的就是200
- 3开头的表示重定向
- 301永久重定向
- 302临时重定向
- 304表示可以在缓存中取数据(协商缓存)
- 4开头表示客户端错误
- 403跨域
- 404请求资源不存在
- 5开头表示服务端错误
- 50
三、DNS
概述: DNS 是域名系统 (Domain Name System) 的缩写,提供的是一种主机名到 IP 地址的转换服务,就是我们常说的域名系统。
作用: 将域名解析为IP地址,客户端向DNS服务器(DNS服务器有自己的IP地址)发送域名查询请求,DNS服务器告知客户机Web服务器的 IP 地址。
解析过程:
- 浏览器缓存:首先在浏览器缓存中查找对应的IP地址,如果查到直接返回,若找不到就继续下一步
- 本地DNS服务器: 将请求发送给本地DNS服务器,在本地域名服务器缓存中查询,如果查找到,就直接将查找结果返回,若找不到继续下一步
- 根域名服务器: 本地DNS服务器向根域名服务器发送请求,根域名服务器会返回一个所查询域的顶级域名服务器地址
- 顶级域名服务器: 本地DNS服务器向顶级域名服务器发送请求,接受请求的服务器查询自己的缓存,如果有记录,就返回查询结果,如果没有就返回相关的下一级的权威域名服务器的地址
- 权威域名服务器: 本地DNS服务器向权威域名服务器发送请求,域名服务器返回对应的结果
- 本地DNS服务器将返回的结果保存在缓存中,便于下次使用
- 本地DNS服务器将返回结果返回给浏览器
- 用户向本地 DNS 服务器发起请求属于递归请求,本地 DNS 服务器向各级域名服务器发起请求属于迭代请求。
比如要查询 www.baidu.com 的 IP 地址,首先会在浏览器的缓存中查找是否有该域名的缓存,如果不存在就将请求发送到本地的 DNS 服务器中,本地DNS服务器会判断是否存在该域名的缓存,如果不存在,则向根域名服务器发送一个请求,根域名服务器返回负责 .com 的顶级域名服务器的 IP 地址的列表。然后本地 DNS 服务器再向其中一个负责 .com 的顶级域名服务器发送一个请求,负责 .com 的顶级域名服务器返回负责 .baidu 的权威域名服务器的 IP 地址列表。然后本地 DNS 服务器再向其中一个权威域名服务器发送一个请求,最后权威域名服务器返回一个对应的主机名的 IP 地址列表。
四、网络模型
- 应用层:为应用程序提供服务
- 表示层:数据格式转化、数据加密
- 会话层:建立、管理和维护会话
- 传输层:建立、管理和维护端到端的连接
- 网络层:IP选址及路由选择
- 数据链路层:提供介质访问和链路管理
- 物理层:物理层
五、TCP和UDP
| UDP | TCP | |
|---|---|---|
| 是否连接 | 无连接 | 面向连接 |
| 是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输(数据顺序和正确性),使用流量控制和拥塞控制 |
| 连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 |
| 传输方式 | 面向报文 | 面向字节流 |
| 首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
| 使用场景 | 适用于实时应用,例如视频会议、直播 | 适用于要求可靠传输的应用,例如文件传输 |
TCP重传机制: TCP在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号。
TCP三次握手:
- 第一次握手: 客户端向服务端发送连接请求报文段。该报文段中包含自身的数据通讯初始序号。请求发送后,客户端便进入 SYN-SENT 状态。
这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
- 第二次握手: 服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入 SYN-RECEIVED 状态。
这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
- 第三次握手: 当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。
这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
三次握手原因:客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。
四次挥手:
- 第一次挥手:若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。
- 第二次挥手:服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。但是因为 TCP 连接是双向的,所以服务端仍旧可以发送数据给客户端。
- 第三次挥手:服务端如果此时还有没发完的数据会继续发送,完毕后会向客户端发送连接释放请求,然后服务端便进入 LAST-ACK 状态。
- 第四次挥手:客户端收到释放请求后,向服务端发送确认应答,此时客户端进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有服务端的重发请求的话,就进入 CLOSED 状态。当服务端收到确认应答后,也便进入 CLOSED 状态。
六、缓存问题
6.1 本地缓存、cookie、token
cookie:网站为了标识用户身份而储存在客户端的数据。(不安全,考虑服务器性能适用cookie),每次http求情都会携带
localStorage和SessionStorage不会自动的把数据发给服务器,只会在本地保存
session:一般是用来跟踪用户状态的,保存在服务端(安全,登录信息保存,其他信息如果需要保留,可以放在cookie中)
存储大小:cookie大小一般不能超过4k,而 **localStorage、SessionStorage比cookie大得多,可以达到5M
有期事件:localStorage关闭浏览器后数据依然保留,除非手动清除,否则一直在
sessionStorage关闭浏览器或者标签后即失效
cookie一般由 server 设置值及过期时间
session的生命周期是间隔的
6.2 浏览器缓存
浏览器对之前请求过的文件进行缓存,以便下一次访问时重复使用,节省带宽,提高访问速度,降低服务器压力
强缓存:浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回,强制缓存的情况主要有三种(暂不分析协商缓存过程),如下:
1. 不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致)
1. 存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存
1. 存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果
当浏览器向服务器发起请求时,服务器会将缓存规则放入HTTP响应报文的HTTP头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Control优先级比Expires高
协商缓存:协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用本地缓存的过程,主要有以下两种情况:
1. 协商缓存生效,返回304
1. 协商缓存失效,返回200和请求结果结果
七、浏览器
7.1 性能优化
- 减少http请求次数
- 对js和css打包,资源合并
- 适用雪碧图,把请求的icon合并成一张图片
- 给资源做缓存
- 图片按需加载(懒加载)
- CDN减少打包体积
- 异步加载js文件
- 开启gzip打包
- 路由懒加载,图片懒加载
- 预渲染和服务端渲染
- 组件的按需加载
7.2 渲染机制
HTML被HTML解析器解析成DOM树css则被css解析器解析成CSSOM树- 结合
DOM树和CSSOM树,生成一棵渲染树(Render Tree) - .根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
- 重绘(Painting):根据渲染树以及回流得到的几何信息,得到节点的绝对像素(像素,背景色,外观等)
- Display将像素发送给GPU,展示在页面上
回流(重排): 当DOM的变化影响了元素位置和尺寸大小,浏览器需要重新计算元素的几何属性
页面第一次加载时进行一次回流
当元素的 width、height、margin、padding、left、top 发生改变的时候会发生回流、
使 DOM节点增减或移动
读写 offset、client、scroll 时,浏览器为了获取这些值,会进行回流操作
使用
window.getComputedStyle的时候
重绘:
- 当改变元素时,只是改变了它的外观,比如背景颜色等,而没有影响到它的布局,这个时候会发生重绘
- 回流(重排)必将引起重绘;重绘不一定会引起回流(重排)
如何避免或减少:
- 避免逐次改变样式,样式统一批量修改
- DOM离线处理,减少回流重绘次数
- 使用document fragment在DOM Tree之外建立一个子树
- position属性控制其脱离文档流
- CSS3硬件加速(GPU加速)
7.3 XSS和CSRF攻击
xss:不需要你做任何的登录认证,它会通过合法的操作(比如在url中输入、在评论框中输入),向你的页面注入脚本(可能是js、hmtl代码块等)。跨域脚本攻击
防御:
- 编码:对用户输入的数据进行HTML Entity 编码。把字符转换成 转义字符。Encode的作用是将$var等一些字符进行转化,使得浏览器在最终输出结果上是一样的。
- 过滤:移除用户输入的和事件相关的属性。
csrf:在未退出A网站的前提下访问B,B使用A的cookie去访问服务器。跨站请求伪造
防御:
- 使用验证码或者 token 验证,每次提交表单时需要带上 token(伪造者访问不到),如果 token 不合法,服务器拒绝请求
- 通过 host+origin 来判断是否为非法用户
- 给 Cookie 设置 SameSite属性,来限制第三方 Cookie,里面有三个值 strict、lax、none
7.4 进程和线程
进程是程序的一次执行,他占有一片独有的内存空间;可以通过windows任务管理器查看
线程是进程内的一个独立执行单元;是程序执行的一个完整的流程;是CPU的最小的调度单元
【联系】: 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程;
资源分配给进程,同一进程的所有线程共享该进程的所有资源;
处理机分给线程,即真正在处理机上运行的是线程;




