面试 -- 计网&浏览器
在浏览器中输入URL并回车后都发生了什么?
- 解析url
http://www.baidu.com/api/?x=1&name=小强&from=http://#hashjs协议:http默认端口80;https默认端口443;FTP(大文件)默认端口21 防止乱码:对整个url进行编码 1. encodeURI 、decodeURI //处理空格,中文 2. encodeURIComponent、decodeURIComponent //主要对传递的参数信息编码 - 客户端想检测是否有强缓存
Expires Cache-ControljsMemory Cache: 内存缓存 Disk Cache:硬盘缓存 1. 首次打开网页,会检查Disk Cache,有则使用,无则发送网络请求 2. 普通刷新(F5),先检查Memory Cache,再检查Disk Cache 3. 强制刷新(ctrl+f5),不走缓存,请求头部均带有Cache-control:no-cache - 协商缓存,有则返回304,客户端再去本地缓存取资源,无则返回200和最新资源
- DNS解析,进入域名系统 找到真实ip地址 ,浏览器将域名解析的映射(真实ip)缓存到本地js
理论上减少DNS请求可以使性能优化(资源放在同一个服务器上) 但项目中不会这么做,服务器拆分的优势 1. 资源的合理利用 2. 抗压能力增强 3. 提高HTTP并发 - 建立连接 TCP三次握手(都不会携带正式数据)
- 请求和传输数据,渲染页面(浏览器渲染页面的整个过程)
- 断开连接(TCP四次挥手)
- 解析url
从哪些点做性能优化?
- webpack层面
- HTTP层面
- 利用缓存
- 对于静态资源文件实现强缓存和协商缓存(扩展:文件有更新,如何保证及时刷新?)
- 对于不经常更新的接口数据采用本地存储做数据缓存(扩展: cookie / localStorage / vuex|redux区别?)
- DNS优化
- 分服务器部署,增加HTTP并发性(导致DNS解析变慢)
- DNS Prefetch(预获取)
- TCP的三次握手和四次挥手
Connection:keep-alive
- 数据传输
- 减少数据传输的大小
- 内容或者数据压缩(webpack等)
- 服务器端一定要开启GZIP压缩(─般能压缩60%左右)
- 大批量数据分批次请求(例如:下拉刷新或者分页,保证首次加载请求数据少)
- 减少HTTP请求的次数(资源文件合并处理、字体图标、雪碧图、图片的BASE64)
- 懒加载,SSR服务端渲染
- CDN服务器“地域分布式”
- 采用HTTP2.0
- 利用缓存
- 延迟、异步加载(异步组件)
- 骨架屏
- 大数据渲染优化
- 大文件传输处理
- 性能与动画
- 减少dom操作,避免回流
- 采用文档碎片(虚拟dom的原理)
- 要操作的元素脱离文档流(定位,浮动,translate)
图片懒加载
- 性能优化,图片在需要的时候才加载,减轻服务的负担,提高页面的加载速度
- 图片的加载是在src的值引起的,对src赋值的时候会请求图片资源,基于这个,我们可以利用html5的自定义属性data-xxx来先保存src的路径,当我们需要加载图片的时候再把data-xxx的值赋予src,就能实现图片的懒加载
- 第三方插件:lazyload
瀑布流布局(自适应)
- 等宽不等高:内容从左到右排列,一行排满之后,其余内容按顺序排在短的一列后
- 计算出一列能够容纳几列元素(可视宽度/单个元素宽度,取整)
- 将后续的元素放在列中高度之和最小的列后面,利用定位
- 等宽不等高:内容从左到右排列,一行排满之后,其余内容按顺序排在短的一列后
Cookie 和 Token 的区别
- 为什么要有 Cookie 呢?
- 一般接口但是通过 HTTP 协议来进行数据交换的,而 HTTP 协议的特点是,无状态,工作前通过三次握手建立连接,工作完成后立刻通过四次挥手断开连接,每次连接都是独立存在的,没有任何状态将请求串联成一个整体,因此每次都需要重新验证是身份,即耗费了性能,也给黑客的攻击留下隐患。
- Cookie 的作用是什么呢,它的出现,就是来弥补 HTTP 无状态的问题的,Cookie 可以作为一个状态保存的状态机,用来保存用户的相关登录状态,当第一次验证通过后,服务器可以通过 set-cookie 令客户端将自己的 cookie 保存起来,当下一次再发送请求的时候,直接带上 cookie 即可,而服务器检测到客户端发送的 cookie 与其保存的 cookie 值保持一致时,则直接信任该连接,不再进行验证操作
- 有了 Cookie 为什么还需要 Token?
- Cookie 作为 HTTP 规范,存在一些历史遗留问题,比如跨域限制,存在默认存储以及默认发送的行为,存在一定的安全性问题
- 相较于 Cookie,token 需要自己存储,自己进行发送,不存在跨域限制,因此 Token 更加的灵活,没有 Cookie 那么多的“历史包袱”束缚,在安全性上也能够做更多的优化。
- Token 有什么 优势?
- Cookie 存储空间 4kb,因此存储的主要是一个用户 id,其他的用户信息都存储在服务器的Session中,对于服务器来说,将是非常大的性能压力
- Token 没有内存限制,用户信息可以存储 Token 中,返回给用户客户端自行存储,避开了性能问题
- 为什么要有 Cookie 呢?
网络安全问题
- XSS(跨站脚本攻击)
- 反射型 XSS:非持久型XSS,构造恶意链接诱导点击,服务器返回带XSS的网页,用户触发XSS,向恶意服务器发送敏感信息
- 存储型 XSS:持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行
- 防范措施 :
- CSRF攻击(跨站请求伪造)
- 伪造恶意网站,诱导用户点击,窃取其真实网站的cookie信息,从而盗号,假冒用户身份操作
- 防范措施:
- 验证 HTTP Referer 字段
- 添加验证码
- 添加 token
- SQL 注入
- 例如上送用户名和密码的时候,黑客猜测登录验证的 SQL 语句大致为
select * from user where user=user and psd=psd;,他可以通过构造用户名user = yimwu';--,使得后台解析语句为select * from user where user='yimwu';--' and psd=psd;,这个语句中--表示注释,就绕过了密码校验 - 防范措施 : 对输入进行细致的过滤,对于相关的关键词进行屏蔽和转义
- 例如上送用户名和密码的时候,黑客猜测登录验证的 SQL 语句大致为
- DDOS(分布式拒绝服务攻击)
- 操作大量僵尸机同时对某网站进行访问,使得网站服务器资源耗尽,宕机
- 防范措施 :针对 DDOS,由于其访问并非同一台主机发起,无法对访问次数进行限制并封禁 IP ,因此在软件层面上是很难进行正对性防御的
- 搭建负载均衡高性能服务器集群
- 部署 CDN
- 部署安全厂商的防火墙
- 购买云 DDOS 高防服务
- 垂直越权
- 例如通过普通账号登录,服务器验密后返回对应权限,黑客通过工具拦截服务器登录成功的响应包,进行角色权限修改,欺骗前端,实现越权
- 防范措施:对于角色控制相关的参数应该做加密处理,或者增加多个隐藏字段来进行权限相关的验证
- 水平越权
- 例如通过普通账号登录,服务器验密后返回对应权限,黑客通过工具对服务器返回的ID码进行拦截分析,前端发起请求,修改Id码,实现水平越权
- 防范措施:对每个接口添加 token 验证,id 必须做到无法猜解
- 文件上传漏洞
- 通过BP对文件上传过程中的数据包截取,把合法后缀修改回来,成功绕过前端检测
- 通过BP对后端检测过程中的content-type字段,把合法后缀修改回来,成功绕过后端检测
- 糅合合法文件头和恶意代码,绕过服务器验证
- WebShell
- 配合文件上传漏洞来上传恶意脚本,诱导服务器执行恶意脚本,连接服务器执行,执行恶意指令
- XSS(跨站脚本攻击)
HTTP和HTTPS
- HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
wepack中loader和plugin的区别
- 由于
webpack本身只能打包commonjs规范的js文件,所以,针对css,图片等格式的文件没法打包,就需要引入第三方的模块进行打包。loader虽然是扩展了webpack,但是它只专注于转化文件(transform)这一个领域,完成压缩,打包,语言翻译。仅仅只是为了打包!!!css-loader和style-loader模块是为了打包css的babel-loader和babel-core模块时为了把ES6的代码转成ES5url-loader和file-loader是把图片进行打包的
plugin也是为了扩展webpack的功能,但是plugin是作用于webpack本身上的。而且plugin不仅只局限在打包,资源的加载上。它的功能要更加丰富。从打包优化和压缩,到重新定义环境变量,功能强大到可以用来处理各种各样的任务。ignore-plugin:用来忽略一些文件html-webpack-plugin:在build中新建一个index.html文件,自动引入打包输出的所有资源(js/css).可以配置 template为新html文件创建模板mini-css-extract-plugin:将css单独打包成一个文件的cssserviceworker-webpack-plugin:离线缓存功能clean-webpack-plugin:用于清除目录文件,在生产环境中编译文件的时候,用它来讲dist的目录清除干净,然后再生成新的webpack-parallel-uglify-plugin:多线程压缩js代码,加快构建速度
loader运行在打包文件之前(loader为在模块加载时的预处理文件),plugins在整个编译周期都起作用。
- 由于
GET和POST的区别
- get用来获取数据,post用来提交数据
- get请求的数据会附加在url之 ,以 " ? "分割url和传输数据,多个参数用 "&"连接,而post请求会把请求的数据放在http请求体中
- get是请求获取指定资源,get方法时安全(从服务器的维度来看)、幂等、可缓存的,get方法的报文主体没有任何语义。post是根据报文主体来对指定资源做出处理,post不安全,不幂等,不可缓存(大部分情况下)。
HTTP1.0 1.1 2.0
- HTTP1.0 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接
- HTTP1.X长连接复用:若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞 线头阻塞
- HTTP2.0多路复用:多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行