当前位置: 首页 > news >正文

网站推广的意义和方法wordpress图片站主题

网站推广的意义和方法,wordpress图片站主题,2018做网站,深圳网站建设怎么办文章目录面-什么是SEO面 - cookie / localstorage / sessionstorage的区别面 - promise面试题面 - 柯里化函数面 - 函数节流面 - 函数防抖HTML / CSS 知识点1、讲讲盒模型#xff08;蚂蚁金服 2019.03 招行信用卡 2019.04 美团 作业帮#xff09;2、根据盒模型解释边距重叠蚂蚁金服 2019.03 招行信用卡 2019.04 美团 作业帮2、根据盒模型解释边距重叠蚂蚁金服 2019.03 图森未来3、 宽高比4:3自适应 蚂蚁金服 2019.03 4、css选择器的优先级 百度前端 搜狐 美团 拼多多 VIVO5、css水平居中 蚂蚁金服、百度前端、字节跳动6、CSS3 的 flexbox弹性盒布局模型以及适用场景 猿辅导7、如何画一个三角形 星环科技8、让一个图片无限旋转蚂蚁金服 2019.039、display 有哪些值说明他们的作用?10、position 的值11、为什么要初始化 CSS 样式12、简要介绍一下CSS3的新特性13、元素的显示与隐藏14、display: none与visibility: hidden的区别15.如何让一个不设宽高的div垂直水平居中16.什么是BFC17.css reset 浏览器样式重置18.常用的几种开发布局方式19-兼容问题渐进增强和优雅降级20-设置p标签属性ie6以下为黑。ie7以下为红20-html/xhtml/xml21-对比一下divcss和table布局22-console23-为什么利用多个域名来提供网站资源会更有效24-谈谈以前端角度出发做好 SEO 需要考虑什么25-rgba()和 opacity 的透明效果有什么不同26 - sass和less27-css3动画和js动画区别28-css3和html5新特性**1、CSS3 新特性有哪些**2.**html5 有哪些新特性、移除了那些元素如何处理 HTML5 新标签的浏览器兼容问题**支持 HTML5 新标签29-image 和 canvas 在处理图片的时候有什么区别30-HTML5中的本地存储介绍一下31- margin塌陷解决方式32- 清浮动方法33- flex34- 常见的布局方式35-css中的1px问题36- CSS实现水平垂直居中37- 层叠上下文和层叠等级38- 移动端的1pxjs知识点面 - js对象隐形转成原始数据类型面 - 基础类型使用方法1.数据类型和方法1-1 操作数组方法2- string对象2.操作符5.类和实例和继承原型和原型链7. ES高级8- DOM面 - onload 和 onDomContentLoaded的区别1- 元素查找2- 事件流3- 事件对象9- BOMLocation对象History对象Navigation对象window对象移动端dom10- js的执行机制10-1 编译过程10-2 代码执行过程10-3 词法作用域/函数作用域/块作用域和闭包10-4 预解析10-5 this面 - 手写new面 - 手写callget和post 的区别面试题3.防抖和节流的区别是什么怎么实现4.深拷贝和浅拷贝有什么区别你能实现一个深拷贝吗浅拷贝实现 只拷贝当前基本属性的值不会拷贝复杂属性的值 俗称只拷贝地址不拷贝内容深拷贝实现 拷贝当前的值复杂属性也一并拿来拷贝全部属性值换个地址而已8.实现一个new函数9.箭头函数和普通函数的区别是什么10.实现一个promise11.promise、async/await、setTimeout的区别是什么vue知识点面- 介绍一下什么是SSR面-vue的跨平台是如何做到的面 - 文件上传的几种方式聊聊大文件上传面 - 组件设计和状态设计1-vue的使用1-1 插值表达式1-2 指令1-3计算属性 和 过滤器 和 监听属性**计算属性** - 多个数据影响一个数据监听属性 - 一个数据影响多个数据每个的使用场景1-4 生命周期1-5 事件监听器1-6 内置组件2-vue高级特性2-1 .$nextTick2-2 组件的name属性 - 递归组件2-3 组件通信面--父传子的生命周期面--父组件监听子组件的生命周期2-3 slot插槽面- 如何在vue中提取可复用的组件2-4 动态组件2-5 异步组件2-6 缓存组件 keep - alive2-7 mixin2-8 自定义指令3-vue底层原理3-1组件化vue核心面--说说组件化工程化和模块化3-2响应式3-3 vdom 和 diff面- 为何要加上key3-4 模板编译3-5 组件更新 和 渲染过程3-6 前端路由原理面- 如何实现vue-router切换页面后保持在页面顶部/保持原先位置不变4-相关插件4-1 axios工具包面--axios如何解决跨域问题4-2 vuex核心面-- 页面刷新的时候数据丢失面 - vuex实现双向绑定4-3 vue-router1-使用步骤2- 编程式导航3-路由元信息4-导航跳转流程5- 获取路由跳转的信息面 - 如何监听路由参数的变化面 - 使用动态路由切换时候组件没有变化不会触发生命周期函数面 - 实现路由解耦4-4 vue-loader5- vue的性能优化5-1 代码层面的优化5-2 Webpack 层面的优化5-3 **基础的** Web 技术的优化面- vue如何优化首屏加载速度React 知识点1- react的使用1-1 创建react元素的方式1-2 jsx{ }嵌入式表达式1-3 条件渲染1-4列表渲染1-5 组件1-6 事件1-7 组件通信1-8 生命周期1-9 setState2- React 高级特性2-1高阶组件公共逻辑代码的抽离minin已经弃用2-2 render - props 公共逻辑代码的抽离mixin已经弃用2-3 Portals 传送门2-4 异步组件2-5 性能优化**代码层面优化**Webpack 层面的优化Web 技术的优化2-6 组件懒加载3- React 核心原理3-1函数式编程3-2 JSX编译3-3 组件渲染过程 和 更新过程3-4 合成事件机制3-5 setState 和 batchUpdate机制面 - React和vue对比webpack知识点1. 什么是webpackwebpack的运行原理如何打包 字节跳动2.什么是bundle,什么是chunk什么是module?3.什么是Loader?什么是Plugin?4. 有哪些常见的Loader他们是解决什么问题的5. 有哪些常见的Plugin6.webpack的构建流程是什么?从读取配置到输出文件这个过程尽量说全7.如何利用webpack来优化前端性能8. 如何提高webpack的打包速度?9. 介绍模块化发展历程10.webpack 热更新原理11-介绍一下babelNODEJS知识点1.模块分类2.node模块类型3-中间件4-node事件循环机制 和 浏览器的事件循环机制4-1 浏览器的事件循环机制小程序面 - 小程序开发和vue开发的区别#$1-文件架构2- 双线程模型3- 小程序执行流程浏览器输入url后发生了什么网络 / 浏览器基本流程1.DNS地址查询2.TCP连接3.发送HTTP请求4.服务器处理请求以及响应5.浏览器根据响应渲染页面6.tcp连接结束1-DNS地址查询1.1什么是DNS1-2 DNS查询1-3 DNS中的安全问题1-4 DNS中的网络性能优化2-TCP连接2-1什么是tcp2-2 三次握手和四次挥手1.**三次握手**2.为什么要三次握手3.四次握手4.为什么要四次挥手5超时和重传6-tcp的可靠性如何保证3-发送HTTP请求3-1.什么是HTTP协议3-2.HTTP连接方式3-3.HTTP报文1-报文格式2-请求方式3-常见的状态码3-4-HTTP版本3-5-HTTPS1.**什么是HTTPS****2- HTTPS功能实现**1.内容被窃听问题 - 加密2.报文被篡改 - 数字签名3-通信方身份伪装 - 数字证书3-4-带宽和延迟4- 浏览器渲染页面4-1浏览器组成4-2 浏览器如何解析资源渲染页面1.渲染引擎将html和css文档解析成语法树2.渲染引擎将css语法树和html语法树结合成渲染树3.渲染引擎和js引擎4.触发浏览器的paint事件根据渲染树计算元素位置绘制5.回流和重绘**浏览器缓存ajax请求和跨域问题1- get 请求和get 请求的区别2- 网络传输常用的数据格式xmljson3- formdata 对象4- 跨域 / 同源解决跨域v8引擎的内存控制垃圾回收机制service worker性能优化WEB安全1.xss攻击1-1 xss介绍1-2 恶意代码注入方式1-3 XSS攻击分类1-4XSS攻击预防2.CSRF攻击2-1 CSRF介绍2-2 攻击类型2-3 CSRF攻击特点2-4 防护策略同源检测防护双重Cookie验证Token防护Samesite Cookie属性2-5 CSRF 测试3.点击劫持攻击4.后端一些攻击漏洞命令行注入和DDos攻击面 - 开发中的数据安全问题开发项目知识点yarnGIT抓包工具linux基本指令开发流程短信验证码和图片验证码移动端的兼容安卓和iOS手机2.CSRF攻击2-1 CSRF介绍2-2 攻击类型2-3 CSRF攻击特点2-4 防护策略同源检测防护双重Cookie验证Token防护Samesite Cookie属性2-5 CSRF 测试3.点击劫持攻击4.后端一些攻击漏洞命令行注入和DDos攻击面 - 开发中的数据安全问题开发项目知识点yarnGIT抓包工具linux基本指令开发流程短信验证码和图片验证码移动端的兼容安卓和iOS手机vue知识点 react知识点完善90% 等上了redux再继续完善 面试视频redux没看react面试题没准备 webpack知识点 html/css知识点 浏览器知识点 网络知识点 安全问题 js知识点 执行上下文/作用域/闭包 概念和刷题this/call/apply/bind 手写原型/继承 概念Promise 看一下深浅拷贝事件机制函数式编程es常用方法webworker防抖节流柯里化函数 typescript git代码管理 小程序 性能优化闲暇看 打包优化网络优化代码优化 node 设计模式 数据结构和算 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a7F4lihL-1598189226388)(C:\Users\ADMINI~1\AppData\Local\Temp\1591770445912.png)] 面-什么是SEO seo 搜索机器人的搜索网页的模式根据网页类型来进行广度和深度搜索。 搜索机器人在搜索到一个网页时候会优先看meta标签的元信息。所以meta内容是增加seo的一个手段。 搜索机器人在爬网页的时候会对网络的内容进行一个过滤然后根据内容相关度比如文本相关度进行排行。而爬网页的过程中如果能让搜索机器人更理解更快更好的处理数据也会增加seo比如标签语义化。 还有一个很重要的seo就是外链。这是前端能做的增强seo最有效的一个方法。搜索机器人会根据外链的数量和自己和对方外置的权重来进行一个计算得出本网站的权重值。 合理的 title、description、keywords搜索对着三项的权重逐个减小title 值强调重点即可重要关键词出现不要超过 2 次而且要靠前不同页面 title 要有所不同description 把页面内容高度概括长度合适不可过分堆砌关键词不同页面 description 有所不同keywords 列举出重要关键词即可重要内容 HTML 代码放在最前搜索引擎抓取 HTML 顺序是从上到下有的搜索引擎对抓取长度有限制保证重要内容一定会被抓取重要内容不要用 js 输出爬虫不会执行 js 获取内容少用 iframe(搜索引擎不会抓取 iframe 中的内容)非装饰性图片必须加 alt提高网站速度(网站速度是搜索引擎排序的一个重要指标) 面 - cookie / localstorage / sessionstorage的区别 cookie一开始只是用来和服务器通信的后来用于存储一些本地数据大小只有4kb发送ajax时自动添加cookie。操作cookie的api简陋 localStorage5M / sessionStorage20M 大容量loacalstorage永久存在浏览器中。sessionstorage只存在当前窗口关闭则清除 cookie cookie机制 客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时浏览器把请求的网址连同该Cookie一同提交给服务器。 cookie 做什么? 一般用来存储数据 比如 用户的登录状态 不过现在经常用token 和localStorage了 HTTP协议本身是无状态的。什么是无状态呢即服务器无法判断用户身份。Cookie实际上是一小段的文本信息key-value格式。客户端向服务器发起请求如果服务器需要记录该用户状态就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie以此来辨认用户等状态。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0SGRNVSD-1598189226390)(C:\Users\ADMINI~1\AppData\Local\Temp\1592384871210.png)] 面 - promise面试题 //题目1 const promise new Promise((resolve, reject) {console.log(1)resolve()//此处不会阻塞console.log(2) }) promise.then(() {console.log(3) }) console.log(4) //1243//题目2 const promise new Promise((resolve, reject) {setTimeout(() {console.log(once)resolve(success)}, 1000) })const start Date.now() promise.then((res) {console.log(res, Date.now() - start) }) //只要promise状态确定了then函数可以一直调用 promise.then((res) {console.log(res, Date.now() - start) })//题目三 Promise.resolve(1).then(2).then(Promise.resolve(3)).then(console.log) // .then 或者 .catch 的参数期望是函数传入非函数则会发生值穿透。 面 - 柯里化函数 柯里化函数是指一个函数在内部定义了一个函数处理参数并将其返回 运行后可以得到新的函数并且该函数能够处理接下来的参数。 面 - 函数节流 限制函数一段时间内只执行一次。防抖和节流都是js性能优化的方式都用于检测鼠标滚轮输入框输入等事件 var throttle function(func, delay) {var prev Date.now();return function() {var context this;var args arguments;var now Date.now();if (now - prev delay) {func.apply(context, args);prev Date.now();}} } function handle() {console.log(Math.random()); } window.addEventListener(scroll, throttle(handle, 1000));面 - 函数防抖 没有防抖前函数持续触发。浪费性能最典型的场景是输入框触发input事件时。这时候可以利用闭包实现函数防抖达到事件出发后一段时间内再执行回调若期间事件还被触发则重新计时。 function debounce(fn, wait) {var timeout null;return function() {if(timeout ! null) clearTimeout(timeout);timeout setTimeout(fn, wait);} } // 处理函数 function handle() {console.log(Math.random()); } // 滚动事件 window.addEventListener(scroll, debounce(handle, 1000));HTML / CSS 知识点 1、讲讲盒模型蚂蚁金服 2019.03 招行信用卡 2019.04 美团 作业帮 盒子模型就是 元素在网页中的实际占位有两种标准盒子模型和IE盒子模型 标准(W3C)盒子模型内容content填充padding边框border边界margin宽高指的是 content 的宽高 低版本IE盒子模型内容contentpaddingborder 边界margin宽高指的是contentpaddingborder 部分的宽高 /* 标准模型 */ box-sizing:content-box;/*IE模型*/ box-sizing:border-box; 复制代码2、根据盒模型解释边距重叠蚂蚁金服 2019.03 图森未来 父子元素、兄弟元素当有外边距时会取其中一个边距的最大值作为实际的边距。 空元素的有上下边距时也会取其中更大的一个边距值作为实际的边距。 这就是边距重叠。 BFC 概念块级格式化上下文 原理 在BFC这个元素垂直方向的边距会发生重叠BFC的区域不会与浮动元素的box重叠BFC在页面上是一个独立的容器其里外的元素不会互相影响计算BFC高度时浮动元素也会参与计算 3、 宽高比4:3自适应 蚂蚁金服 2019.03 垂直方向的padding: 在css中padding-top或padding-bottom的百分比值是根据容器的width来计算的。 .wrap{position: relative;height: 0; //容器的height设置为0width: 100%;padding-top: 75%; //100%*3/4 } .wrap *{position: absolute;//容器的内容的所有元素absolute,然子元素内容都将被padding挤出容器left: 0;top: 0;width: 100%;height: 100%; } 复制代码**padding calc()**: 跟第一种方法原理相同 ​css padding-top: calc(100%*9/16); 复制代码padding 伪元素视窗单位 浏览器100vw表示浏览器的视窗宽度 width:100vw; height:calc(100vw*3/4) 复制代码4、css选择器的优先级 百度前端 搜狐 美团 拼多多 VIVO 优先级就近原则同权重情况下样式定义最近者为准 !importantid classtag important比内联优先级高 元素选择符的权值元素标签派生选择器1class选择符10id选择符100内联样式权值最大为1000 !important声明的样式优先级最高如果冲突再进行计算。如果优先级相同则选择最后出现的样式。继承得到的样式的优先级最低。 5、css水平居中 蚂蚁金服、百度前端、字节跳动 一、对于行内元素 text-align:center; 复制代码二、对于确定宽度的块级元素 1margin和width实现水平居中 常用(前提已设置width值)margin-left:auto; margin-right:auto; 2绝对定位和margin-left: -(宽度值/2)实现水平居中 固定宽度块级元素水平居中通过使用绝对定位以及设置元素margin-left为其宽度的一半 .content{width: 200px;position: absolute;left: 50%;margin-left: -100px; // 该元素宽度的一半即100pxbackground-color: aqua;} 复制代码3position:absolute left0top0right0bottom0 margin:auto .content{position: absolute;width: 200px;top: 0;right: 0;bottom: 0;left: 0;margin: auto;} 复制代码三、对于未知宽度的块级元素 1table标签配合margin左右auto实现水平居中 使用table标签或直接将块级元素设值为display:table再通过给该标签添加左右margin为auto 2inline-block实现水平居中方法 displayinline-block;或display:inline和text-align:center;实现水平居中 复制代码存在问题需额外处理inline-block的浏览器兼容性解决inline-block元素的空白间距 3绝对定位实现水平居中 绝对定位transformtranslateX可以移动本省元素的50% .content{position: absolute;left: 50%;transform: translateX(-50%); /* 移动元素本身50% */background: aqua;} 复制代码4相对定位实现水平居中 用float或者display把父元素变成行内块状元素 .contentParent{display: inline-block; /* 把父元素转化为行内块状元素 *//*float: left; 把父元素转化为行内块状元素 */position: relative;left: 50%;}/*目标元素*/.content{position: relative;right: 50%;background-color:aqua;} 复制代码5CSS3的flex实现水平居中方法法一 .contentParent{display: flex;flex-direction: column;}.content{align-self:center;} 复制代码6CSS3的flex实现水平居中方法法二 .contentParent{display: flex;}.content{margin: auto;} 复制代码7CSS3的fit-content配合左右margin为auto实现水平居中方法 .content{width: fit-content;margin-left: auto;margin-right: auto;} 复制代码参考链接 blog.csdn.net/dengdongxia… 6、CSS3 的 flexbox弹性盒布局模型以及适用场景 猿辅导 该布局模型的目的是提供一种更加高效的方式来对容器中的条目进行布局、对齐和分配空间。在传统的布局方式中block 布局是把块在垂直方向从上到下依次排列的而 inline 布局则是在水平方向来排列。弹性盒布局并没有这样内在的方向限制可以由开发人员自由操作。flexbox设置父元素的display属性为flex则子元素都变成flex item通过自己内部的格式化规则。可以控制子元素的排列方式、尺寸、间距等 试用场景弹性布局适合于移动前端开发在Android和ios上也完美支持。 7、如何画一个三角形 星环科技 左右边框设置为透明长度为底部边框的一半。左右边框长度必须设置不设置则只有底部一条边框是不能展示的。 {width: 0; height: 0; border-top: 40px solid transparent; border-left: 40px solid transparent; border-right: 40px solid transparent; border-bottom: 40px solid #ff0000;} 复制代码8、让一个图片无限旋转蚂蚁金服 2019.03 img classcircle src001.jpg width400 height400///infinite 表示动画无限次播放 linear表示动画从头到尾的速度是相同的.circle{animation: myRotation 5s linear infinite;} keyframes myRotation {from {transform: rotate(0deg);}to {transform: rotate(360deg);} } 复制代码9、display 有哪些值说明他们的作用? inline默认。此元素会被显示为内联元素元素前后没有换行符。 block此元素将显示为块级元素此元素前后会带有换行符。 none此元素不会被显示隐藏。 inline-block行内块元素。CSS2.1 新增的值 list-item此元素会作为列表显示。 table此元素会作为块级表格来显示类似table表格前后带有换行符 10、position 的值 absolute 生成绝对定位的元素相对于 static 定位以外的第一个父元素进行定位。 元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。 fixed 生成固定定位的元素相对于浏览器窗口进行定位。老IE不支持 元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。 relative 生成相对定位的元素相对于其正常位置进行定位不脱离文档流。 因此“left:20” 会向元素的 LEFT 位置添加 20 像素。 static默认值。 没有定位元素出现在正常的文档流中忽略 top, bottom, left, right 或者 z-index 声明。inherit规定应该从父元素继承 position 属性的值。 11、为什么要初始化 CSS 样式 因为浏览器的兼容问题不同浏览器对有些标签的默认值是不同的如果没对CSS初始化往往会出现浏览器之间的页面显示差异。 12、简要介绍一下CSS3的新特性 在布局方面新增了flex布局 在选择器方面新增了例如:first-of-type,nth-child等选择器 在盒模型方面添加了box-sizing来改变盒模型 在动画方面增加了animation、2d变换、3d变换等。在颜色方面添加透明、rgba等 在字体方面允许嵌入字体和设置字体阴影同时当然也有盒子的阴影 媒体查询。为不同设备基于它们的能力定义不同的样式。 media screen and (min-width:960px) and (max-width:1200px){body{background:yellow;} } 复制代码13、元素的显示与隐藏 元素的显示隐藏方法很多不同方法的在不同的场景下页面效果不一对页面的性能也有不同的影响。 元素隐藏方法总结 如果希望元素不可见、不占据空间、资源会加载、DOM 可访问 display: none 如果希望元素不可见、不能点击、但占据空间、资源会加载可以使用 visibility: hidden 如果希望元素不可见、不占据空间、显隐时可以又transition淡入淡出效果 div{ position: absolute;visibility: hidden;opacity: 0;transition: opacity .5s linear;background: cyan; }div.active{visibility: visible;opacity: 1; } 复制代码这里使用visibility: hidden而不是display: none是因为display: none会影响css3的transition过渡效果。 但是display: none并不会影响cssanimation动画的效果。 如果希望元素不可见、可以点击、占据空间可以使用 opacity: 0如果希望元素不可见、可以点击、不占据空间可以使用 opacity: 0; position: absolute;如果希望元素不可见、不能点击、占据空间可以使用 position: relative; z-index: -1;如果希望元素不可见、不能点击、不占据空间可以使用 position: absolute ; z-index: -1; 14、display: none与visibility: hidden的区别 display: none的元素不占据任何空间visibility: hidden的元素空间保留display: none会影响css3的transition过渡效果visibility: hidden不会display: none隐藏产生重绘 ( repaint ) 和回流 ( relfow )visibility: hidden只会触发重绘株连性display: none的节点和子孙节点元素全都不可见visibility: hidden的节点的子孙节点元素可以设置 visibility: visible显示。visibility: hidden属性值具有继承性所以子孙元素默认继承了hidden而隐藏但是当子孙元素重置为visibility: visible就不会被隐藏。 15.如何让一个不设宽高的div垂直水平居中 ​ 方法一使用css3方法的transfrom. 11 方法二给父盒子设置display:table-ceil,这样子盒子就相当于表格内的元素和可以通过text-align和vertical-align对齐 16.什么是BFC BFC叫做块级格式化上下文。它制造了一个独立的渲染区域有着自己特殊的布局方式和外部不同。 内部布局规则有 块级元素按垂直方向一个个放置box的垂直方向距离由margin控制bfc不会和浮动元素重叠bfc内容高度包括浮动元素 触发方式 根元素htmlfloat属性不为noneposition为absolute或者fixeddisplay为inline-block,table-captionoverflow不为visible 17.css reset 浏览器样式重置 每个浏览器对页面样式的处理方式不一样。所以有时候写样式的时候会把这些浏览器差异化的样式统一清除后编写样式。但是实际上样式初始化会对seo有一定的影响。所以我们要在保持最小损失的情况下达到相对大的效果。 18.常用的几种开发布局方式 流式布局/百分比布局 设置盒子的宽度的时候采用百分比取值使之能够小范围内根据屏幕宽度调整元素距离。但是和设计图会有偏差。 fflex布局 rem布局 媒体查询通过查询screen宽度来设置根元素字体大小然后标签属性的尺寸单位设置成rem。 超小768px 小屏768-992 中屏992-1200 大屏1200 通常使用响应式框架来开发网页比如boostrap 19-兼容问题渐进增强和优雅降级 渐进增强是优先针对低版本的浏览器进行构建页面保证最基本的功能然后针对高级浏览器进行效果交互功能的进一步优化。 优雅降级是一开始就是构建一个完整的功能然后再对低版本浏览器进行一个向下兼容的处理甚至是阉割。比如css3h5的一些特型低版本处理不了 20-设置p标签属性ie6以下为黑。ie7以下为红 这是css hack p{color: green,//可以理解为特定浏览器下的私有属性*color:red,_color:black }20-html/xhtml/xml html是网页设计的语言 xhtml是xml的过度语言和html类似只是规则上有些差异比如Xhtml必须有闭合标识。必须有根元素 xml是可拓展标记语言和html语法规则类似但是xml它用于传递数据且xml标签完全自定义 21-对比一下divcss和table布局 table布局其实我基本没用过。只是自己练习的时候操作了一下。所以也只能简单的对比一下两者的差异 divcss能够提高seo相对于table来说很大程度上提高了网页的浏览速度。而且容易维护和改版 table局部麻烦代码量大不容易维护seo差 22-console console.info(“这是info”); console.log(“这是log”); console.debug(“这是debug”); console.warn(“这是warn”); console.error(“这是error”); ​ console.dir(‘这是dir’) ​ console.group(“第一组信息”); console.log(“第一组第一条”); console.log(“第一组第二条”); console.groupEnd(); 23-为什么利用多个域名来提供网站资源会更有效 突破浏览器的并发限制 现阶段各大浏览器的同一域名最大的并发请求数量在6个或以上低版本的IE6、7是2个。节约cookie带宽 在访问服务器时cookie也会占用一定的带宽使用多个域名进行分流。CDN缓存更方便 多个域名可以更快速的给客户端分配最优下载服务器传输数据更快。防止不必要的安全问题例如cookie的隔离 客户端对服务器进行请求时发送数据到达的地址会用一个第三方的域名。防止上传恶意数据对cookie进行窃取。节约主机域名连接数优化页面响应速度 这个很显然每个域名所响应的客户端请求越少反应时间也就越短客户端页面可以更快下载数据。 24-谈谈以前端角度出发做好 SEO 需要考虑什么 搜索机器人的搜索网页的模式根据网页类型来进行广度和深度搜索。 搜索机器人在搜索到一个网页时候会优先看meta标签的元信息。所以meta内容是增加seo的一个手段。 搜索机器人在爬网页的时候会对网络的内容进行一个过滤然后根据内容相关度比如文本相关度进行排行。而爬网页的过程中如果能让搜索机器人更理解更快更好的处理数据也会增加seo比如标签语义化。 还有一个很重要的seo就是外链。这是前端能做的增强seo最有效的一个方法。搜索机器人会根据外链的数量和自己和对方外置的权重来进行一个计算得出本网站的权重值。 合理的 title、description、keywords搜索对着三项的权重逐个减小title 值强调重点即可重要关键词出现不要超过 2 次而且要靠前不同页面 title 要有所不同description 把页面内容高度概括长度合适不可过分堆砌关键词不同页面 description 有所不同keywords 列举出重要关键词即可 重要内容 HTML 代码放在最前搜索引擎抓取 HTML 顺序是从上到下有的搜索引擎对抓取长度有限制保证重要内容一定会被抓取 重要内容不要用 js 输出爬虫不会执行 js 获取内容 少用 iframe(搜索引擎不会抓取 iframe 中的内容) 非装饰性图片必须加 alt 提高网站速度(网站速度是搜索引擎排序的一个重要指标) 25-rgba()和 opacity 的透明效果有什么不同 rgba()和 opacity 都能实现透明效果但最大的不同是 opacity 作用于元素以及元素内的所有 内容的透明度 而 rgba()只作用于元素的颜色或其背景色。设置 rgba 透明的元素的子元素不会继承透明效果 26 - sass和less ​ sass和less都属于css的预处理器是专门用一种语言来为css增加一点编程的特性最终输出css文件。 至于为什么使用这些css预处理器。因为css本身的语法有很多不足比如不能嵌套书写没有变量和合理的样式复用机制。难以维护。 less对比sass的优点 less使用环境更简单只要能运行js就能处理less文件。而cass需要安装ruby环境less使用上手简单十分贴合css只是增加一个些变量等复用性强的语法规则 -sass优势 有变量作用域函数进程控制继承数据结构等 27-css3动画和js动画区别 js动画功能更加强大兼容性更好 js对于动画的控制粒度更细css只能通过keyframs来控制。css动画被支持的时间函数很少不灵活现阶段而言css动画很难做到多个状态的转化只要支持js的客户端都能展示出来 css优势性能好 css是样式制作的动画性能消耗比较少css3属性有很大的兼容问题对于帧速表现不太好的浏览器css可以自然降级 28-css3和html5新特性 1、CSS3 新特性有哪些 答1.颜色新增 RGBAHSLA 模式 \2. 文字阴影text-shadow、 3.边框 圆角border-radius边框阴影 box-shadow \4. 盒子模型box-sizing 5.背景background-size 设置背景图片的尺寸 background-origin 设置背景图片的原点 background-clip 设置背景图片的裁切区域以””分隔可以设置多背景用于自适应布局 6.渐变linear-gradient、radial-gradient \7. 过渡transition可实现动画 \8. 自定义动画 animate keyfrom \9. 在 CSS3 中唯一引入的伪元素是 selection. \10. 媒体查询多栏布局 media screen and (width:800px){ … } \11. border-image 12.2D 转换transformtranslate(xy) rotate(xy) skew(xy) scale(xy) \13. 3D 转换 14 字体图标 font-face 15 弹性布局 flex 2、CSS3 选择器有哪些 答属性选择器、伪类选择器、伪元素选择器。 属性选择器 例如:[href“a.mp4”] {color: green;} 伪类选择器 例如:li:nth-child(3) {color: red;} span:empty h2:target li:not(.special) li:nth-last child(3) {color: blue;} 伪元素选择器 例如:p::selection p::first-line li::first-letter after bofer 2.html5 有哪些新特性、移除了那些元素如何处理 HTML5 新标签的浏览器兼容问题 新特性 \1. 拖拽释放(Drag and drop) API ondrop 自定义属性 data-id 获取 li.getAttribute(‘data-id’)或者 li.dataset.type ‘guoji’ \2. 语义化更好的内容标签header,nav,footer,aside,article,section \3. 音频、视频 API(audio,video) 如果浏览器不支持自动播放怎么办 \4. 画布(Canvas) API 热 canvas 和 image 的区别 \5. 地理(Geolocation) API \6. 本地离线存储 localStorage 长期存储数据浏览器关闭后数据不丢失 \7. sessionStorage 的数据在浏览器关闭后自动删除 \8. 表单控件calendar、date、time、email、url、search 、tel、file、number \9. 新的技术 webworker, websocket, Geolocation 10文件读取 移除的元素-纯表现的元素basefontbigcenterfont, sstrikettu 支持 HTML5 新标签 * IE8/IE7/IE6 支持通过 document.createElement 方法产生的标签 可以利用这一特性让这些浏览器支持 HTML5 新标签 浏览器支持新标签后还需要添加标签默认的样式 * 当然最好的方式是直接使用成熟的框架、使用最多的是 html5shim 框架 !--[if lt IE 9] script srchttp://html5shim.googlecode.com/svn/trunk/html5.js/script ![endif]--29-image 和 canvas 在处理图片的时候有什么区别 答image 是通过对象的形式描述图片的canvas 通过专门的 API 将图片绘制在画布上。 30-HTML5中的本地存储介绍一下 标签之间的通信和购物车都会用到本地存储 以前我们在存储本地得到时候都会存储在cookie里面但是cookie存储大小只有4k而且解析复杂。而且cookie数据在发送请求的时候会自动发送给浏览器。造成更大的问题 存储空间html5 localstorage20m和sessionStorage5m提供了一个新的本地存储方式存储空间更大操作更简易。 生命周期sessionStorage。在浏览器窗口关闭时清除。local storage需要手动清除。cookie在过期之前一直有效。 作用域 sessionStorage要想数据共享必须在同一个浏览器内。localstorage和cookie在所有的同源窗口中共享 31- margin塌陷解决方式 给父元素设定一个border-top / padding-top限定子元素的margin 给父元素设定overflowhidden 触发BFC 给父元素设定浮动 将父元素转成行内块元素 32- 清浮动方法 额外标签法 给父元素后添加块元素添加属性clearboth 伪元素清楚法 原理和额外标签清除一样只不过换成了为元素 给父元素设定overflowhidden 给父元素设定一个高度 33- flex 单行内 水平方向 justify-content space-between 垂直方向 align- center 是否换行 flex-wrapwrap 多行侧轴 align-content : space - around flex - basic 元素初始大小优先级比width高 34- 常见的布局方式 流式布局百分比布局flex布局弹性布局响应式布局grid布局 35-css中的1px问题 12 - 哪些操作会导致回流 调整窗口大小Resizing the window改变字体Changing the font增加或者移除样式表Adding or removing a stylesheet内容变化比如用户在input框中输入文字Content changes, such as a user typing text in an input box激活 CSS 伪类比如 :hover (IE 中为兄弟结点伪类的激活)Activation of CSS pseudo classes such as :hover (in IE the activation of the pseudo class of a sibling)操作 class 属性Manipulating the class attribute脚本操作 DOMA script manipulating the DOM计算 offsetWidth 和 offsetHeight 属性Calculating offsetWidth and offsetHeight设置 style 属性的值 Setting a property of the style attribute 36- CSS实现水平垂直居中 划重点这是一道面试必考题很多面试官都喜欢问这个问题我就被问过好几次了 要实现上图的效果看似很简单实则暗藏玄机本文总结了一下CSS实现水平垂直居中的方式大概有下面这些本文将逐一介绍一下我将本文整理成了一个github仓库欢迎大家star 仅居中元素定宽高适用 absolute 负marginabsolute margin autoabsolute calc 居中元素不定宽高 absolute transformlineheightwriting-modetablecss-tableflexgrid absolute 负margin 为了实现上面的效果先来做些准备工作假设HTML代码如下总共两个元素父元素和子元素 div classwpdiv classbox size123123/div /div 复制代码 wp是父元素的类名box是子元素的类名因为有定宽和不定宽的区别size用来表示指定宽度下面是所有效果都要用到的公共代码主要是设置颜色和宽高 注意后面不在重复这段公共代码只会给出相应提示 /* 公共代码 */ .wp {border: 1px solid red;width: 300px;height: 300px; }.box {background: green; }.box.size{width: 100px;height: 100px; } /* 公共代码 */ 复制代码 绝对定位的百分比是相对于父元素的宽高通过这个特性可以让子元素的居中显示但绝对定位是基于子元素的左上角期望的效果是子元素的中心居中显示 为了修正这个问题可以借助外边距的负值负的外边距可以让元素向相反方向定位通过指定子元素的外边距为子元素宽度一半的负值就可以让子元素居中了css代码如下 /* 此处引用上面的公共代码 */ /* 此处引用上面的公共代码 *//* 定位代码 */ .wp {position: relative; } .box {position: absolute;;top: 50%;left: 50%;margin-left: -50px;margin-top: -50px; } 复制代码 这是我比较常用的方式这种方式比较好理解兼容性也很好缺点是需要知道子元素的宽高 点击查看完整DEMO absolute margin auto 这种方式也要求居中元素的宽高必须固定HTML代码如下 div classwpdiv classbox size123123/div /div 复制代码 这种方式通过设置各个方向的距离都是0此时再讲margin设为auto就可以在各个方向上居中了 /* 此处引用上面的公共代码 */ /* 此处引用上面的公共代码 *//* 定位代码 */ .wp {position: relative; } .box {position: absolute;;top: 0;left: 0;right: 0;bottom: 0;margin: auto; } 复制代码 这种方法兼容性也很好缺点是需要知道子元素的宽高 点击查看完整DEMO absolute calc 这种方式也要求居中元素的宽高必须固定所以我们为box增加size类HTML代码如下 div classwpdiv classbox size123123/div /div 复制代码 感谢css3带来了计算属性既然top的百分比是基于元素的左上角那么在减去宽度的一半就好了代码如下 /* 此处引用上面的公共代码 */ /* 此处引用上面的公共代码 *//* 定位代码 */ .wp {position: relative; } .box {position: absolute;;top: calc(50% - 50px);left: calc(50% - 50px); } 复制代码 这种方法兼容性依赖calc的兼容性缺点是需要知道子元素的宽高 点击查看完整DEMO absolute transform 还是绝对定位但这个方法不需要子元素固定宽高所以不再需要size类了HTML代码如下 div classwpdiv classbox123123/div /div 复制代码 修复绝对定位的问题还可以使用css3新增的transformtransform的translate属性也可以设置百分比其是相对于自身的宽和高所以可以讲translate设置为-50%就可以做到居中了代码如下 /* 此处引用上面的公共代码 */ /* 此处引用上面的公共代码 *//* 定位代码 */ .wp {position: relative; } .box {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%); } 复制代码 这种方法兼容性依赖translate2d的兼容性 点击查看完整DEMO lineheight 利用行内元素居中属性也可以做到水平垂直居中HTML代码如下 div classwpdiv classbox123123/div /div 复制代码 把box设置为行内元素通过text-align就可以做到水平居中但很多同学可能不知道通过通过vertical-align也可以在垂直方向做到居中代码如下 /* 此处引用上面的公共代码 */ /* 此处引用上面的公共代码 *//* 定位代码 */ .wp {line-height: 300px;text-align: center;font-size: 0px; } .box {font-size: 16px;display: inline-block;vertical-align: middle;line-height: initial;text-align: left; /* 修正文字 */ } 复制代码 这种方法需要在子元素中将文字显示重置为想要的效果 点击查看完整DEMO writing-mode 很多同学一定和我一样不知道writing-mode属性感谢张鑫旭老师的反馈简单来说writing-mode可以改变文字的显示方向比如可以通过writing-mode让文字的显示变为垂直方向 div classdiv1水平方向/div div classdiv2垂直方向/div 复制代码 .div2 {writing-mode: vertical-lr; } 复制代码 显示效果如下 水平方向 垂 直 方 向 复制代码 更神奇的是所有水平方向上的css属性都会变为垂直方向上的属性比如text-align通过writing-mode和text-align就可以做到水平和垂直方向的居中了只不过要稍微麻烦一点 div classwpdiv classwp-innerdiv classbox123123/div/div /div 复制代码 /* 此处引用上面的公共代码 */ /* 此处引用上面的公共代码 *//* 定位代码 */ .wp {writing-mode: vertical-lr;text-align: center; } .wp-inner {writing-mode: horizontal-tb;display: inline-block;text-align: center;width: 100%; } .box {display: inline-block;margin: auto;text-align: left; } 复制代码 这种方法实现起来和理解起来都稍微有些复杂 点击查看完整DEMO table 曾经table被用来做页面布局现在没人这么做了但table也能够实现水平垂直居中但是会增加很多冗余代码 tabletbodytrtd classwpdiv classbox123123/div/td/tr/tbody /table 复制代码 tabel单元格中的内容天然就是垂直居中的只要添加一个水平居中属性就好了 .wp {text-align: center; } .box {display: inline-block; } 复制代码 这种方法就是代码太冗余而且也不是table的正确用法 点击查看完整DEMO css-table css新增的table属性可以让我们把普通元素变为table元素的现实效果通过这个特性也可以实现水平垂直居中 div classwpdiv classbox123123/div /div 复制代码 下面通过css属性可以让div显示的和table一样 .wp {display: table-cell;text-align: center;vertical-align: middle; } .box {display: inline-block; } 复制代码 这种方法和table一样的原理但却没有那么多冗余代码兼容性也还不错 点击查看完整DEMO flex flex作为现代的布局方案颠覆了过去的经验只需几行代码就可以优雅的做到水平垂直居中 div classwpdiv classbox123123/div /div 复制代码 .wp {display: flex;justify-content: center;align-items: center; } 复制代码 目前在移动端已经完全可以使用flex了PC端需要看自己业务的兼容性情况 点击查看完整DEMO grid 感谢一丝姐 反馈的这个方案css新出的网格布局由于兼容性不太好一直没太关注通过grid也可以实现水平垂直居中 div classwpdiv classbox123123/div /div 复制代码 .wp {display: grid; } .box {align-self: center;justify-self: center; } 复制代码 37- 层叠上下文和层叠等级 层叠上下文 如果一个元素内部发生了元素层叠则称这个元素为层叠上下文元素。 在同一个层叠上下文中层叠等级越高的越在z轴高出显示 不同层叠上下文层叠等级的比较要先比较层叠上下文叠层等级 38- 移动端的1px 根据设备型号比如375设备和750设计稿将0.5px转成rem使用边框图边设置meta元属性的视口以方便适配手机端 39 - input宽度 并不是给所有元素设定displayblock该元素就会填充父元素宽度。input的就不会input宽度只由size决定 js知识点 面 - js对象隐形转成原始数据类型 如果对象存的是原始数据类型那就不需要转换了。调用x.valueOf(),入股转换成基础数据类型返回对应的值调用.toString(),如果转成基础类型返回如果都没有返回报错 面 - 基础类型使用方法 基础类型当在调用方法的时候浏览器内部会将他转成对象然后调用原型链上的方法。 调用完后销毁对象转成初始值 1.数据类型和方法 numberstringbooleanundefinenullObjectfunctionArray 1-1 操作数组方法 .join() 将数组转成字符串用自定义的字符串分割 .push() 将数据放在最后一项返回一个长度 .pop() 将数组最后一项移除返回移除的值 .shift() 删除数组第一项返回该项 .unshift在数组第一项加上一项/多项返回长度 .sort() 对数组进行排序 .reverse() 反向排序数组 .concat() 合并数组 .slice( index1,index2) 数组截取返回截取的新数组 .splice() 删除数组项添加数组项 indexof / lastindexof查找已知数据返回第一次/最后一次出现的下标没有则返回-1 es5 .forEach() 遍历数组将每项交给回调处理 .map()遍历数组将每项交给回调处理返回一个新函数 .filter() 返回一个数组包含满足回调函数条件的元素 .some() 判断是否有元素满足条件 .every() 判断是否全符合条件 .find() 找到第一个满足条件的元素 2- string对象 简单的数据类型本身是没有操作数据的方法的他们只有数据若简单数据类型使用了属性和方法浏览器底层会将其包装成复杂数据类型操作结束后又会基本包装类型 .trim()去除字符串首位空格 .touppercase()转大写字母 .slice()字符串切割 .replace()字符串替换 es6 .startsWith() 是否以指定字符串开头 .endsWith() 是否以指定字符串结尾 .includes() 2.操作符 typeof - typeof str 返回数据类型 检测数据类型基本数据类型都能识别复杂数据类型都是object。null由于二进制的前三位和对象是一样的所以也被识别为object instanceof A instanceof B - 判断B是否在A原型链上返回布尔值 Object.getPrototypeOfobj 逻辑运算符 A B 返回遇到的第一个falsely值都是ture返回B A || B 返回第一个truely值 比较运算符 类型不同会隐形转换尽量让他们相等 除非 null 其他一律用 in 操作符 检查该属性是不是在原型链上 Object.hasOwnProperty()检查属性是不是在该实例上 Object.create(B) 将B添加为对象的原型 Object.keysobj 遍历对象提取key放入数组 Object.assigntarget… sources 浅复制 for … of … 迭代这个对象 5.类和实例和继承 类是将数据和它相关的行为打包起来就称之为类。在其他语言中子类和父类类和实例都是完全不同的对象子类将父类的成员复制过来加以处理形成自己的属性和方法。 原型/构造函数这两个概念是js里面独有的在js中用这两者来模拟类的概念。构造函数中有一个属性指向原型原型有一个默认属性指向构造函数当构造函数实例化后new强行构建了一个对象称之为实例。实例上有构造函数执行时获得的方法当调用自己没有的方法时实例的内部[[get]]属性会自动向对象的__proto_属性指向的对象中查找这个对象就是实例。若该原型的身上也没有该方法【【get】】内部属性会继续通过–proto–找原型的原型就这样[[get]]持续查找的过程直到查找到null这中间通过–propto–属性链接起来的链式结构称之为原型链。一些插件就是在原型上添加了相关的接口而已。 继承是面向对象编程的三大特征之一。就是将有着共同成员的类的成员提取出来单独定义成一个类若需要定义多个子类的时候已经在父类定义好了的成员就不用重新定义了。由于js中的原型和构造函数的特殊性有很多种继承方式。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XuYLpOGh-1598189226398)(C:\Users\ADMINI~1\AppData\Local\Temp\1592389657228.png)] 封装面向对象编程的三大特征之一。对象内部 可以定义外部访问不到的私有属性 多态对象在实例化的时候对类的方法重新赋值。就造成了一个函数名的两种使用方式。 原型和原型链 原型每个函数都有 prototype 属性该属性指向原型对象使用原型对象的好处是所有对象实例共享它所包含的属性和方法。原型链主要解决了继承的问题每个对象都拥有一个原型对象通过__proto__ 指针指向其原型对象并从中继承方法和属性同时原型对象也可能拥有原型这样一层一层最终指向 null。 7. ES高级 解构赋值 计算变量 模板字符串 展开运算符 set对象去重 箭头函数 箭头函数没有内部属性this只能在词法作用域找外部的this。没有内部属性arguments没有propertype属性this无法用call等改变 模块的导出和导入 es6的模块导入是静态导入在导入前会先进行编译。所以配合webpack能实现一些代码优化。 promise() [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HdAfj7bZ-1598189226399)(C:\Users\ADMINI~1\AppData\Local\Temp\1592389471451.png)] 解决异步中的回调函数问题回调地狱。阅读性差 promise对象内部有一个状态机当调用reject或者resole函数时候状态机的值就会改变执行then或者catch函数。 实质上是对Generator 生成器函数的包装 async 和 await 关键字 async 修饰一个函数标识这个函数异步执行。 await 会阻塞async函数的执行直到内部 定义的一个promise对象得到成功的结果。只接收成功的结果若防止失败。用try/catch包裹整个await代码 let/const 声明关键字会定义一个块作用域每次声明都会创建一个块作用域。 for(let i 0 ,i 10, i){console.log(i) } //等同于 { let i 0 ,log(i) } { let i 1 ,log(i) } { let i 2 ,log(i) } { let i 3 ,log(i) } { let i 4 ,log(i) } ​代码执行到一块作用域的时候编译器会创建词法作用域环境此时声明提升。 编译器遇到var关键字的时候会查找该变量有没有声明如果声明了就直接不再创建变量标识符若没有则创建并自动赋值为undifine。v当编译器遇到let关键词时创建和查找过程和var一样和var不同的是let的词法环境是块作用域内。const关键词和let差不多只是const关键词声明的变量的内部属性的[[write]]属性值为false。 在let/const声明变量后到js引擎给变量赋值的过程变量里面没有保存任何数据连undfine都没有这段过程称为暂时性死区。 let/const的变量提升最多只能提升到script作用域变量 迭代器 iterator是一个接口为不同的数据提供一个访问机制完成遍历操作。 数组的很多高级方法内部都是调用了迭代里来遍历数组执行流程如下 被遍历的对象会调用[Symbol.iterator]方法该方法返回一个迭代器对象对象指针指向1该对象可以调用next方法该会返回包含1号项信息的value和done属性的对象。指针指向2一直调用next直到done变成true 迭代器在es6中使用的场景很多 解构赋值扩展运算符数组/伪数组的方法set对象去重 es6 moudle 静态导入编译后才会导入数据。自动采用严格模式。导出的都是值的引用 import导入会返回一个promise对象可以通过这个进行懒加载 import“”.then() Proxy 是一个构造函数可以生成一个拦截对象实例访问任何该对象的行为都要先经过拦截对象。 我们回想一下vue 2对数组的拦截方式只能通过在实例和对象之间增加一个拦截原型来监听几个数组方法。而proxy对象是在访问该对象之间建立了一个对象。 宏任务主代码。i/oui render 8- DOM 面 - onload 和 onDomContentLoaded的区别 1- 元素查找 找到的dom元素伪数组 2- 事件流 注册事件 事件源.on事件名 函数 事件源.addEventListener( “事件名”事件处理函数布尔值 ) 有兼容性通过布尔值控制事件处理函数的触发时机true在捕获阶段执行 移除事件 事件源.on事件名 null事件源.removeEventListener( “事件名”事件处理函数 ) 3- 事件对象 在事件触发后会创建一个事件对象存入事件相关信息。 浏览器自动将事件对象存入事件处理函数中只要在事件处理函数接收就好了 event.target 注册和绑定事件的对象 event.currentTarget 触发点击的对象 event.perventDefault()阻止对象默认行为 event.stopPropagation()阻止事件流传递 9- BOM Location对象 包含了网站的url信息和操作 History对象 存储浏览器的历史记录 Navigation对象 存储了客户端的信息 window对象 offsetWIdth : 当前元素信息 clientwidth当前元素可视区信息 scroll 滚动条信息 移动端dom touch相关事件。click事件会有300ms延迟 事件对象 e.touches: 屏幕上所有触点 10- js的执行机制 10-1 编译过程 阶段一词法分析阶段 将代码拆分成token词法单元块 阶段二: 语法分析 将token转成AST抽象语法树 阶段三代码生成 AST 转译成机器码 作用域就是收集和维护所有声明标识符的超集 10-2 代码执行过程 编译器声明代码在词法作用域内查找是否有变量标记符若没有则在该作用域创建该标识符 声明提升预解析过程 声明多个函数后面覆盖前面的声明同名函数和变量函数生效 js引擎执行代码的时候会在当前词法作用域查找有没有a若有直接操作数据没有继续向上查找 LHS查询被赋值的变量RHS查询查找变量 10-3 词法作用域/函数作用域/块作用域和闭包 作用域就是一个变量的合法使用范围。在这个范围内RHS能查询到该变量 词法作用域是词法分析过程就定下来了作用域而闭包就是指函数在执行的时候能够访问声明时候所在的词法作用域此时就产生了闭包。 闭包可以用来保护数据模块导入防抖节流 10-4 预解析 10-5 this this指向函数调用的 执行环境对象所以this的绑定决定于函数的调用方式可以通过函数调用栈查找 函数自调用 this指向全局对象 对象调用 this指向该对象 call/apply/bind直接绑定 new绑定 特殊调用 定时器中的函数属于函数自调用 函数发生赋值传递时候原this指向会丢失 面 - 手写new 创建一个新对象继承构造函数的原型考虑参数绑定this指向 function newOperator(ctor){if(typeof ctor ! function){throw newOperator function the first param must be a function;}// ES6 new.target 是指向构造函数newOperator.target ctor;// 1.创建一个全新的对象// 2.并且执行[[Prototype]]链接// 4.通过new创建的每个对象将最终被[[Prototype]]链接到这个函数的prototype对象上。var newObj Object.create(ctor.prototype);// ES5 arguments转成数组 当然也可以用ES6 [...arguments], Aarry.from(arguments);// 除去ctor构造函数的其余参数var argsArr [].slice.call(arguments, 1);// 3.生成的新对象会绑定到函数调用的this。// 获取到ctor函数返回结果var ctorReturnResult ctor.apply(newObj, argsArr);// 小结4 中这些类型中合并起来只有Object和Function两种类型 typeof null 也是object所以要不等于null排除nullvar isObject typeof ctorReturnResult object ctorReturnResult ! null;var isFunction typeof ctorReturnResult function;if(isObject || isFunction){return ctorReturnResult;}// 5.如果函数没有返回对象类型Object(包含Functoin, Array, Date, RegExg, Error)那么new表达式中的函数调用会自动返回这个新的对象。return newObj; } 面 - 手写call //手写一个call Object.prototype.myCall function (obj, str) {obj.xxx this // this是指向函数obj.xxx(str)}dog.say.myCall(cat, 我是)get和post 的区别 GET比POST更不安全因为参数直接暴露在URL上所以不能用来传递敏感信息。 GET参数通过URL传递POST放在Request body中。 GET请求参数会被完整保留在浏览器历史记录里而POST中的参数不会被保留 GET 请求可被收藏为书签 POST 不能被收藏为书签 GET请求只能进行url编码而POST支持多种编码方式。 GET 请求可被缓存 POST 请求不会被缓存 GET 请求有长度限制POST 请求对数据长度没有要求 面试题 3.防抖和节流的区别是什么怎么实现 防抖触发事件的n秒后执行对应函数若n秒内事件再次被触发那么时间将重新计算。 function debounce(fn, time) {let timer null; // 定时器IDreturn function() {clearTimeout(timer); // 触发事件时将上一次的定时器清除掉timer setTimeout(() { // 创建一个新的定时器只有在一定时间后会执行fn.apply(this, arguments);}, time);}} 复制代码节流触发事件后,会先判断n秒内是否执行了函数未执行时才会去执行。 function throttle(fn, time) {let isRun false; // 定义一个当前事件内是否执行了函数的变量return function () {if (isRun) return; // 如果当前时间内函数执行了则直接returnisRun true; // 没执行则将其设置为truesetTimeout(() { // 创建一个定时器在n秒后执行函数并把isRun赋值为falsefn.apply(this, arguments);isRun false;}, time);}} 复制代码4.深拷贝和浅拷贝有什么区别你能实现一个深拷贝吗 浅拷贝只能复制对象的第一层,当对象的属性还是引用类型的时候则只会复制其引用地址当值被修改以后所有的引用的值都会改变。 赋值拷贝Object.assign扩展运算符 深拷贝则是解决浅拷贝存在的无法深入拷贝复杂类型 JSON对象的parse和stringify 可以满足基本的深拷贝需求能够处理所有能用json格式标识的所有数据类型。但是对于正则表达式和函数类型无法进行深拷贝会丢失很多信息。也会抛弃对象的chonstructor 递归函数 浅拷贝实现 只拷贝当前基本属性的值不会拷贝复杂属性的值 俗称只拷贝地址不拷贝内容 var a function(obj) {// 只拷贝对象if (typeof obj ! object) return;// 根据obj的类型判断是新建一个数组还是对象var newObj obj instanceof Array ? [] : {};// 遍历obj并且判断是obj的属性才拷贝for (var key in obj) {//查找当前对象是否有这个属性if (obj.hasOwnProperty(key)) {newObj[key] obj[key];}}return newObj;} 深拷贝实现 拷贝当前的值复杂属性也一并拿来拷贝全部属性值换个地址而已 var c {name:wangyu,yu:{age: 18}}function a(obj) {var newobj null;if(typeof obj object obj ! null){newobj obj instanceof Array ? [] : {};for(var key in obj){newobj[key] a(obj[key]) }return newobj;}else{return newobj obj}}var qwe a(c)qwe.ewq 20;console.log(qwe);console.log(c);7.在ES5中比较常见的继承方式有哪些 8.实现一个new函数 function _new(Fn,...arg) {// 必须为一个函数且不能为箭头函数if(typeof Fn ! function || !Fn.prototype) throw Error(Fn is not a constructor);// 将新对象的隐式原型赋值为构造函数的prototypeobj.__proto__ Fn.prototypeconst obj Object.create(Fn.prototype);// 改变Fn的执行作用域并传入相应的参数const isRet Fn.call(obj, ...arg);// 判断构造函数本身是否返回一个objectreturn isRet instanceof Object ? isRet : obj;} 复制代码9.箭头函数和普通函数的区别是什么 自身无this其this继承上一级所以无法使用call、apply、bind绑定this自身无 arguments 对象会通过作用域链向上查找不能用作 Generator 函数。没有prototype属性所以无法用new关键字调用 10.实现一个promise 我当时实现的是非常低配的promise,代码就不贴了推荐坤坤大佬的promise实现 11.promise、async/await、setTimeout的区别是什么 首先js的事件循环分为宏任务和微任务而当前执行栈的执行顺序为同步代码 - 微任务中的代码 - 宏任务中的代码。 promisepromise函数本身是同步执行的只有其then或者catch等方法是异步执行的并且其回调函数会被放在事件循环中的微任务队列让同步代码先执行。async/await当一个函数被添加async关键字的时候表明当前函数中可能会有异步方法await关键字只能在async函数中使用并且后面跟一个表达式在async函数中遇见await关键字时会同步执行后面的表达式并将表达式后面的代码放入微任务队列让同步代码先执行。setTimeout/setInterval定时器中的回调函数会被放在宏任务队列等同步代码和微任务队列中的代码执行完毕后执行 vue知识点 面- 介绍一下什么是SSR SSR 又称服务端渲染底层实现逻辑有点像同构。大概的一个流程时在服务端运行一遍代码后拿到html文件将其 客户端渲染的问题 在客户端渲染时会先加载html解析html后再请求一次JavaScript文件渲染生成页面。首屏加载事件慢甚至出现白屏。客户端渲染的seo能力很弱。搜索引擎的识别内容主要还是html文件。 ssr解决方式ssr技术会让框架代码现在服务端执行一遍用户第一次请求的时候已经获得了完整的html文件节省了一个周期的http请求时间。也利于seo。在客户端再执行一遍代码后又给了静态html交互的能力。缺陷ssr技术让原本简单的项目执行起来十分复杂项目的可维护性降低debugger变得复杂。所以如果项目对首屏加载速度和seo需求不是那么大尽量不适用ssr 面-vue的跨平台是如何做到的 虚拟dom本质上就是一个js对象实际开发中都是对这个对象进行操作。跨平台只要在vue的适配层添加响应的适配代码根据不同的平台做出不同的对外接口。 面 - 文件上传的几种方式聊聊大文件上传 1.普通上传方式 将文件进行编码后上传然后服务端解码 - 图片转base64上传 但是转换后的代码往往比源文件更大所以只适合传递一些小文件 使用formdata对象上传文件。而且formdata可以直接整合表单信息统一上传。只是使用不灵活 将整个请求完全交给浏览器或许会出现请求超时 2.大文件上传 ​ 主要问题在于大文件上传的时候花费时间太长如果发送失败必须从头再来 切片上传 通过编码方式上传文件通过slice方法对文件二进制内容进行切片处理给每一个切片添加序号。服务端就可以还原切片了 断点续传 在上传一个文件的时候如果出现意外上传失败下次上传时候可以接着进度上传文件。可以通过xhr对象的方法检测文件时上传的进度将其保存在本地下载上传的时候从本地存储获得进度重新开始上传 进度暂停和停止 可以通过xhr上的方法对文件上传进行一个暂停和继续 面 - 组件设计和状态设计 根据组件功能分析设计适合这个组件的状态 状态设计 要用状态描述所有内容数据要结构化易于代码执行操作适配组件使用数据结构要是可拓展性的比如数组和对象切莫嵌套太深遍历影响性能 组件设计 从功能层次拆分代码尽量让组件原子化一个组件负责一个功能然后根据需求自由组合区分容器组件只负责数据一般是顶层组件和视图组件只显示视图和用户交互 设计步骤 分析页面的功能然后根据功能逐步拆分成组件分析页面的组件的数据流决定好数据结构和容器组件 1-vue的使用 1-1 插值表达式 插值表达式中只能访问data数据和部分全局变量如MathDate 1-2 指令 vue指令是vue框架对于一些操作的封装在模板编译的时候会解析成相对应的js代码执行通过接收参数通过.添加修饰符以完成不同 的操作。 常传的参数有v-bind的属性名 常用的修饰符有 处理数据修饰符 .lazy懒同步.number 数据转成数字类型同步到后台。.trim去掉首尾空白。.once 事件修饰符 .stop() 阻止事件冒泡.prevent()阻止默认行为.once()事件只触发一次.self() 只能在自身触发不能事件委托.capture()在捕获阶段触发 按键修饰符 .键盘码.键盘别名 v-model 只是一个语法糖内部封装了针对该元素的事件和属性的绑定。可以通过自定义model完成很多操作比如组件之间更方便的传值。 v-if 和 v-show v-if底层是通过js判断改向vnode添加哪项节点所以如果没有符合要求该元素直接不会渲染。 v-show则是操作该元素的diaplay属性。 看情况使用两者 v-for 和 v-if v-for 底层和react的列表渲染原理很像遍历该数据将该数据每一项转成一个有结构的数据类型可以说是虚拟dom结构吧。。不能再同一个标签是同时使用这两个v-for的优先级更高 v-once 只解析一次 1-3计算属性 和 过滤器 和 监听属性 计算属性 - 多个数据影响一个数据 计算属性实质上是对插值表达式的一个优化方案。将过重的插值表达式逻辑挂载在实例上但是存在作用域问题。所以出现了过滤器。 而且计算属性对于某个计算结果会进行缓存若数据没有变化多次计算直接返回缓存的值。同时对该数据设置setter和getter当该数据发生变化时计算属性能够检测到再重新计算。倘若长时间不调用计算属性则缓存的空间会被释放。 初始化的时候 计算属性不会求值然后当我们的 render 函数执行访问到 computed相关依赖 的时候就触发了计算属性的 getter它会拿到计算属性对应的 watcher然后执行 watcher.depend()然后再去求值。 初始化过后 当computed的依赖发生变化的时候就触发了计算属性的 getter通知所有订阅它变化的 watcher 更新执行 watcher.update() 方法。如果页面中没有订阅computed的变化就不会求值当下次再访问这个计算属性的时候才会重新求值。 我们要记住这一点不仅仅是计算属性依赖的值发生变化而是当计算属性最终计算的值发生变化才会触发渲染 watcher 重新渲染。 监听属性 - 一个数据影响多个数据 监听属性则是对data中的数据设置了监听当数据变化的时候执行对应的函数必要的时候还要开启深度监听由于深度监听是递归监听到底所以这个方法十分消耗性能要谨慎使用。需要执行异步操作或者一些开销比较大的操作时候监听属性更实用 计算属性其实和监听属性实现原理方面都是差不多的vue的data挂载在实例上的时候当数据变化后先调用watcher观察者模式。然后调用计算属性和观察属性 每个的使用场景 watch 属性适用于观测某个值的变化去完成一段复杂的业务逻辑。 computed 属性适合用在模板渲染中某个值是依赖了其它的响应式对象甚至是计算属性计算而来如果是一个属性依赖多个属性变化的时候。当数据监听 过滤器需要对全局数据进行某种操作的时候 1-4 生命周期 生命周期这个概念其实很抽象我更原理理解为在组件某个阶段钩子函数的触发。 初始化阶段将data数据挂载到vm实例中对数据进行数据劫持。 beforeCreated 函数 - 是new Vue后触发的第一个钩子当前所有的数据都不能访问 挂载vue-router / vuex created函数 - 实例创建完成后此时可以使用数据/但无法操作dom除非使用$nextTick. 找html中的挂载节点通过el属性或者手动$mount设置 找用于渲染的模板 beforeMount - 挂载之前此时模板已经导入渲染函数编译。虚拟dom已经创建完成。此时也可以对数据进行更改不会触发update。 mounted函数dom完成更新.完成数据双向绑定。可以用$ref获取dom 更新阶段当data中依赖项使用的数据发生变化的时候开始更新阶段 beforeUpdate 函数 - 响应式数据发生更新虚拟dom重新渲染前触发此时修改数据不会触发重渲染。update函数 通过虚拟dom进行diff算法对比通过patch算法对新dom树进行操作然后渲染出来 销毁阶段从视图中销毁dom释放子组件事件监听器等资源,若组件销毁后对应的事件没有销毁会报错 beforeDestroy 函数实例销毁之前此时还能操作实例destroyed函数组件销毁完成 1-5 事件监听器 我们可以用$emit定义事件可以被事件监听器监听到事件监听函数甚至可以监听生命周期函数 $on - 持续监听事件$once - 只监听一次事件$off - 停止监听事件 1-6 内置组件 component /transition /Keep - alive /slot/ 2-vue高级特性 2-1 .$nextTick vue在数据改变后会对dom进行相对于的更新而nextTick是在dom更新完成后触发的函数。处于减少dom操作次数的性能优化考虑在一个宏任务里面的只要监听到了数据变化vue会开启一个队列并缓冲在这次宏任务中的所有数据变更都会在最后整合成一次数据变化达到重复数据修改的去重操作。然后更新虚拟dom此时nextTick是在dom更新完成后触发的函数。处于减少dom操作次数的性能优化考虑在一个宏任务里面的只要监听到了数据变化vue会开启一个队列并缓冲在这次宏任务中的所有数据变更都会在最后整合成一次数据变化达到重复数据修改的去重操作。然后更新虚拟dom此时nextTick是在dom更新完成后触发的函数。处于减少dom操作次数的性能优化考虑在一个宏任务里面的只要监听到了数据变化vue会开启一个队列并缓冲在这次宏任务中的所有数据变更都会在最后整合成一次数据变化达到重复数据修改的去重操作。然后更新虚拟dom此时nextTick函数触发。所以一方面我们的数据修改不能依赖上一个数据修改的值另一方面想要操作数据修改后的dom要通过$nextTick函数好 原理vue会根据当前浏览器环境优先使用promise.then和mutationObserver如果不支持用settimeout代替 2-2 组件的name属性 - 递归组件 可以自己将自己注册成自己的子组件用name属性调用达到组件递归的效果。用v-if结束递归。 2-3 组件通信 vue组件之间是封闭的不能互相访问数据要想传输数据必须通过传递属性的方式传递。由于单项数据流父组件数据更新时候子组件接收的数据自动更新而且父组件的传递的数据只能父组件自己来修改。 父子propsparent/parent/parent/children , provide / inject , ref , $attrs / $listeners provide / inject 注入依赖在祖先组件中向后代组件注入数据无论层级多深子组件总能访问到该数据在组件封装的时候还是很好用的 兄弟组件evenBus vuex跨级通信evenBus , vuex , provide / inject , $attr / $listeners 面–父传子的生命周期 父组件给子组件传递数据的时候 父组件开始更新 - 子组件1开始更新 - 子组件1更新完成- 子组件2开始更新 - 子组件2更新完成 - 父组件更新完成 面–父组件监听子组件的生命周期 方法1- 父组件向子组件传递一个函数props值为生命周期函数名子组件通过$emit()提交相应的生命周期函数 // Parent.vue Child mounted“doSomething”/ // Child.vue mounted() { this.$emit(“mounted”); } 复制代码 复制代码 方法2- 在父组件引用子组件时通过 hook 来监听即可如下所示 // Parent.vue Child hook:mounteddoSomething /ChilddoSomething() {console.log(父组件监听到 mounted 钩子函数 ...); },// Child.vue mounted(){console.log(子组件触发 mounted 钩子函数 ...); }, // 以上输出顺序为 // 子组件触发 mounted 钩子函数 ... // 父组件监听到 mounted 钩子函数 ... 复制代码 复制代码当然 hook 方法不仅仅是可以监听 mounted其它的生命周期事件例如createdupdated 等都可以监听。 2-3 slot插槽 插槽在我看来也是只是定制化组件时让组件通信之间能够实现标签传递提高组件的复用性和个性化。 根据使用方式不同分为匿名插槽具名插槽和作用域插槽。 作用域插槽能根据子组件数据来定制化数据 面- 如何在vue中提取可复用的组件 一般我们在开发的时候如果遇到组件在能在多处使用或者多个组件需要使用同于一套处理逻辑。我们会考虑将其抽离提取成一个可复用的组件。 复用组件的三个核心api prop接收外部组件传递的数据定制化可复用的组件emit可以提交触发事件函数slot在可复用组件内根据外部组件传入的数据定制化可复用的组件 2-4 动态组件 动态组件时根据条件的改变来操作组件的渲染情况常见于is和v-for component :is 组件名 / //通过is来控制组件渲染// is属性配合v-for可以实现用动态组件通过数据结构来实现页面展示data:{0:{type:text,msg:1111},1:{type:img,msg:2222},2:{type:text,msg:333}}div v-for (val,key) in data//根据数据结构的不同展示不同的组件。component :is value.type text ? textComponent : imgComponent //div2-5 异步组件 异步组件主要是针对大组件的加载较慢的问题让他按需引入。如果不使用这个组件则永远不加载。 在路由中component{return ‘组件地址’} 在组件注册时候组件地址写成component{return ‘组件地址’} 2-6 缓存组件 keep - alive keep- alive组件包裹组件是若组件反复切换时候组件的状态会被缓存下来。 没有缓存的组件每次切换展示的生命周期mouted - destroy 缓存的组件每次切换展示的生命周期只有第一次加载的时候会出现mouted切换时不会出现destroy 2-7 mixin mixin挺像react里面的高级组件。将组件相同逻辑的内容抽离出来放置到一个配置对象里面。谁需要这个配置就用mixin混入该配置选项。 mixin类似于extend继承方法都是抽离出一个组件配置对象然后混入extend的先执行extend的组件就叫做继承组件 问题 1.mixin阅读不明确 2.多mixin会有冲突 3.mixin和组件之间存在多对多的关系逻辑混乱 2-8 自定义指令 通过控制5个钩子函数来实现自定义指令 3-vue底层原理 3-1组件化vue核心 组件化并不是一个新鲜的词前端的组件化是从后端发展过来加以进化的。后端组件化也能给组件注入数据但是没办法做到通过参数定制组件。前端可以通过数据驱动视图来更好的控制和维护组件。 其中vue数据驱动视图的原理就是MVVM。 面–说说组件化工程化和模块化 工程化 将项目进行分析构建达到开发的时候文件结构清晰分工明确提高开发效率的目的组件化 根据业务逻辑的不同将重复的代码提取出来合并成一个组件在需要的使用该功能的地方使用该组件。侧重于业务的解耦。模块化 将分属于同一功能/业务的代码单独封装成独立的模块可以独立运行。在业务的框架层面来通过接口互相调用。降低业务模块之间的耦合。 相互之间的关系组件化和模块化时工程化的具体体现而组件往往用于模块中处理业务模块的功能需求 3-2响应式 响应式驱动时建立在object.defineProperty()和寄存器getter和setter方法实现的一直设计模型这个设计模型里面有观察者和订阅者模式这个设计模型的核心机制和vm模块 监听对象Obeserver dep watcher 通过Observer给data中的每个属性转换成getter和setter的形式。object.defineProperty()当视图元素通过触发watcher来向data里面获取数据该元素就会被收集到getter里面的依赖项列表中。当数据发生变化的时候setter会监听到遍历getter里面的依赖项列表通过watcher来逐个通知依赖项更新数据 递归深度监听对象属性递归到底浪费性能新增的数据无法监听 监听数组 数组无法直接监听数据本身因为数组是通过方法来改变数组的内容所以我们只能监听操作数组的方法来达到数组的数据的监听。操作数据的方法基本都在数组原型上面为了不污染全局数组原型可以用object.creted在数组实例和原型之间设置一个拦截器。监听拦截器里面的方法。数组操作数据后本身没有该方法就顺着原型链往上查找在找到数组原型之前就在拦截器上找到了该方法。拦截器上的方法一旦被使用就会将这个依赖收集起来。一旦数组数据变化通知所以依赖项 只能监听数组的部分方法。 3-3 vdom 和 diff 虚拟Dom 由于原生的命令式dom操作十分消耗性能且不容易维护vue是数据驱动视图采用了vdomjs用树状对象来模拟dom的结构中的关键节点。将dom操作的计算放到js计算中。数据发生改变的时候js计算出新旧dom的最小变更然后一次性操作dom。这样会很大程度节省性能。 div className father我是divli 我是li标签/li /divconst vDom {tag:div,props:{//属性对象className :father},children:[我是div{tagli,props:[],children:[我是li标签]}] }diff算法 diff算法用于在数据改变后比较新旧vdom的数据结构找出两个数据不同的地方然后更新改变的节点。由于树数据结构的diff算法时间复杂度是On^3,所以vue里面的diff算法有三个规则 只比较同一级别的节点不跨级比较tag属性一旦不同直接删除重建不再深入比较tag和key相同时直接认为时相同节点不再深度比较也不会动他。 vdom操作流程 模板标签 h 函数 创建虚拟dom vnode函数 vnode patch 函数对比新旧dom 渲染页面 addvnodes函数 removenode函数 面- 为何要加上key 在进行diff算法的时候能够快速标记不用遍历检查的vnode减少性能消耗。在增删节点的时候key能帮diff算法更加精准的定位要需要更新的位置。 3-4 模板编译 将vue模板转成能在js中操作的代码js即可执行模板中的插值表达式指令。 内部实现流程 将模板解析成AST (解析器) 遍历整个模板找到html标签标记{{}}插值表达式 遍历AST找到{{}}插值表达式 优化器 标记解析{{}}插值表达式语法 生成渲染函数 代码生成器 解析完{{}}插值表达式生成渲染函数 渲染函数核心语法是with语法。包含插值表达式的表达式可以直接访问data中的数据。 div v-if flag true 我是div标签 /div //渲染函数 withthis{ //vm实例每一个插值表达式都通过这样的形式访问vm数据return creatElement (div)[flag true ? 我是div标签 ] // 内部可以直接访问data中的数据 }执行渲染函数得到vnode 将vnode传入patch函数将vnode渲染到dom节点中。 注webpack使用vue-loader的时候会自动编译模板。若没有提前编译就要在浏览器中编译 3-5 组件更新 和 渲染过程 模板 模板编译 渲染函数 vnode 渲染页面 初次渲染流程 将模板解析为渲染函数响应式系统收集数据依赖项执行render函数生成vnode执行patch函数渲染页面 更新阶段流程 data数据变化触发setter重新执行render函数生成新的vnodepatch函数对比新旧vnode渲染 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7QFy0p5H-1598189226402)(C:\Users\ADMINI~1\AppData\Local\Temp\1591669577786.png)] 3-6 前端路由原理 vue路由是为了实现SPA单页应用vue是单页应用所以当我们在页面进行一些操作改变路由的变化是是不会向服务器发送请求的浏览器监听到url的变化从而更新页面。 有两种模式 两种模式都是返回单页面应用只是地址栏显示不一样。 1、hash 例如 juejin.im/#/index 多用于to B 业务的后台管理系统 hash模式是用window.hashchange的方法监听url当URL的hash部分改变时页面不会重新加载。并且向服务端发送的请求是https://juejin.im/部分 注意 页面刷新的时候不会向服务器发送请求 2、history 例如 [juejin.im/index 多用于toC的业务模式 history模式充分利用 history.pushStateAPI来完成URL跳转而无须重新加载页面。主要使用 history.pushState、history.popState和history.replaceState改变URL。使用history模式我们需要在路由里面加这行代码mode:history然后需要后端配置一个覆盖所有情况的候选资源如果URL匹配不到任何静态资源则应该返回同一个index.html页面这个页面就是你 app 依赖的页面。 router.push、 router.replace 和 router.go 跟 window.history.pushState、 window.history.replaceState 和 window.history.go好像 实际上它们确实是效仿 window.history API 的。 注意 页面刷新的时候会向服务器发送请求,而用此时的url向地址发送请求时后来需要处理url返回根页面。 面- 如何实现vue-router切换页面后保持在页面顶部/保持原先位置不变 vue-router提供了一个scrollBehavior在切换路由额时候可以控制页面是滚到底部还是保持原先位置。只在history模式下可以用。 4-相关插件 4-1 axios工具包 基于promise的http库底层依赖是XMLHttpRequest 发送ajax的工具包底层实际上是使用了promise异步实现的。 面–axios如何解决跨域问题 axios不支持jsonp跨域 针对后台不支持options要么让后台使用cors插件要我么自己写一个后台进行反向代理 请求拦截器统一处理axios的请求后发送请求响应拦截器拿到响应数据后先处理一遍 4-2 vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store仓库。“store” 基本上就是一个容器它包含着你的应用中大部分的状态 ( state )。 1Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候若 store 中的状态发生变化那么相应的组件也会相应地得到高效更新。 2改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WUv4SEc5-1598189226402)(C:\Users\ADMINI~1\AppData\Local\Temp\1591768522198.png)] 核心 state 为单一状态树在state中需要定义我们所需要管理的数组、对象、字符串等等getters 类似vue的计算属性主要用来过滤一些数据。mutation 更改store中state状态的唯一方法就是提交mutationstore.commit。action actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。module module其实只是解决了当state中很复杂臃肿的时候module可以将store分割成模块每个模块中拥有自己的state、mutation、action和getter。 面-- 页面刷新的时候数据丢失 使用本地存储vuex数据使用插件 面 - vuex实现双向绑定 如果直接同时使用v-model绑定vuex中的数据数据修改时会报错因为state中的数据不是经过mutation修改的。 使用设有setter的计算属性绑定v-model计算属性内部调用mutation方法手动绑定state的值在value身上然后监听事件事件回调函数使用mutation的值修改state 4-3 vue-router 1-使用步骤 准备好路由组件定制路由规则挂载路由规则到组件上 2- 编程式导航 通过调用函数将hash值调入history栈中用户后退也鞥返回。声明式导航内部调用了history栈 3-路由元信息 可以在路由跳转的时候存储信息 4-导航跳转流程 导航触发在失活的组件中调用离开守卫调用全局前置守卫判断是否允许该用户访问前往的网页调用重用组件内的组件更新守卫在路由配置中调用组件解析异步路由全局解析守卫导航被确认afterEach函数调用dom更新 5- 获取路由跳转的信息 this.$route.query this.$route.params 面 - 如何监听路由参数的变化 使用watch属性来监听hash值的变化使用beforeRouteUpdate守卫 面 - 使用动态路由切换时候组件没有变化不会触发生命周期函数 watch url的变化为router - view 添加唯一的key为路由地址 面 - 实现路由解耦 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wsWEtTel-1598189226403)(C:\Users\ADMINI~1\AppData\Local\Temp\1591668715781.png)] 4-4 vue-loader 作用1.vue-loader是webpage里面的一个加载器主要用于解析提取vue文件里面的代码比如逻辑代码js样式代码style已经html模板再将他们交给对应的loader去处理。 2.提前对html模板进行模板编译 5- vue的性能优化 5-1 代码层面的优化 v-if 和 v-show 区分使用场景 computed 和 watch 区分使用场景 v-for 遍历必须为 item 添加 key且避免同时使用 v-if 长列表性能优化 事件的销毁 图片资源懒加载 路由懒加载 第三方插件的按需引入 优化无限列表性能 服务端渲染 SSR or 预渲染 5-2 Webpack 层面的优化 Webpack 对图片进行压缩减少 ES6 转为 ES5 的冗余代码提取公共代码模板预编译提取组件的 CSS优化 SourceMap构建结果输出分析Vue 项目的编译优化 5-3 基础的 Web 技术的优化 开启 gzip 压缩浏览器缓存CDN 的使用使用 Chrome Performance 查找性能瓶颈 面- vue如何优化首屏加载速度 首屏加载数据是指浏览器刚打开页面时候出现的内容 使用CDN资源,减小服务器带宽压力路由懒加载将一些静态js css放到其他地方如OSS减小服务器压力按需加载三方资源如iview,建议按需引入iview中的组件使用nginx开启gzip减小网络传输的流量大小若首屏为登录页可以做成多入口登录页单独分离为一个入口使用uglifyjs-webpack-plugin插件代替webpack自带UglifyJsPlugin插件 使用CDN资源,减小服务器带宽压力 在index.html中引入cdn资源 ...bodydiv idapp/div!-- built files will be auto injected --script srchttps://cdn.bootcss.com/vue/2.5.2/vue.min.js/scriptscript srchttps://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js/scriptscript srchttps://cdn.bootcss.com/vuex/3.0.1/vuex.min.js/scriptscript srchttps://cdn.bootcss.com/vue-resource/1.5.1/vue-resource.min.js/script/body...修改 build/webpack.base.conf.js module.exports {context: path.resolve(__dirname, ../),entry: {app: ./src/main.js},externals:{vue: Vue,vue-router: VueRouter,vuex:Vuex,vue-resource: VueResource},... }修改src/main.js src/router/index.js 注释掉import引入的vue,vue-resource // import Vue from vue // import VueResource from vue-resource // Vue.use(VueResource)路由懒加载 require.ensure方式 const workCircle r require.ensure([], () r(require(/module/work-circle/Index)), workCircle) const workCircleList r require.ensure([], () r(require(/module/work-circle/page/List)), workCircleList)import方式 const workCircle () import(/module/work-circle/Index)将一些静态js css放到其他地方如OSS减小服务器压力 注意这里的js文件需要将结果抛出然后在需要用到该js的组件中import引入 按需加载三方资源如iview,建议按需引入iview中的组件 按需引用请查看iview官方文档iview *使用nginx开启gzip减小网络传输的流量大小 React 知识点 1- react的使用 1-1 创建react元素的方式 react.creatElement(标签名/组件名属性对象子元素 …)jsx语法内部转换成React.creatElement() 1-2 jsx{ }嵌入式表达式 在jsx格式中{}里面的内容会动态解析由js执行。 1-3 条件渲染 react中的条件渲染三种方式 在函数中通过条件判断return哪种结构用||和逻辑判断符号用三元运算符 1-4列表渲染 需要知道的一点是jsx中如果插入数组数组的内容会全部展示在jsx中渲染的每一项要加上key属性。 所以可以通过map方法。将数组里面的每一项数据来实现相对于的结构然后后展示在jsx中。 1-5 组件 函数组件 无状态组件 函数组件是一个纯函数输入props。输出jsx结构 类组件有状态组件 受控组件 表单元素里面的value/chencked值和state中的值绑定配合onChange事件得到输入的值才能修改state值表单才能正常显示数值。 受控组件的onChange函数可以总结为一个函数 非受控组件 不受state控制没有和state绑定死值。 通过ref来实现操作该元素dom拿到dom值 1-6 事件 事件对象 react用自己的操作事件的逻辑对事件对象做了一个封装。 传参的时候事件对象默认放在参数的最后一位 this指向 在JavaScript中函数的传递会让this指向丢失。 箭头函数调用内部函数 onClick { this.handleClick() } //直接在内部调用了事件函数this借用了render的this类实例方法 //用箭头函数将函数定义在实例上函数内部使用的时constroctor中的this handleClick (参数event) { console.log(this) } bind返回一个绑定好this的函数 // 1.在事件函数绑定的时候使用bind onClick this.handleClick.bind(this) //this绑定到了render里面的this// 2.在构造函数中bind好constroctor中的this , 不用每次使用的时候都bind返回一个数据 this.handleClick this.handleClick.bind(this)1-7 组件通信 props props是组件父组件给子组件传递数据的一个集合是一个对象。可以通过propType插件来校验和限制props数据的传递子组件通过this.props得到传递数据的对象 父传子 父组件通过给子组件标签添加属性来传递任意类型数据。 子传父父组件给子组件传入一个能改变自己值的函数。 非父子状态提升给组件a传递数据给组件b传递操作该数据的方法。 context 用于跨组件传递数据生产者/消费者模型。 提供者组件为子组件提供数据消费者组件的子组件能够使用这些数据 const {Provider , Consumer} React.createContext1-8 生命周期 创建阶段 constructor() 提供初始化数据创建ref等元素挂载到实例身上处理函数的this指向 render 渲染视图 componentDidMount() 视图渲染完成 发送ajax请求初始化dom操作 更新阶段 shouldComponentUpdate() 更加新旧的比较来决定的该组件需不需要更新。setState/props更新/强制更新触发 render componentDidUpdate() 销毁阶段 不展示该组件 componentWillUnmount() 卸载完成前需要手动清除自己添加的定时器和自定义事件 1-9 setState React中不能直接通过声明式修改state的数据必须通过setstate更新state的数据。 作用 修改了state更新了视图 特点 有时异步react的普通使用有时同步定时器自定义事件 在react内部函数使用setstate时数据异步更新必须等到此次宏任务的微任务中执行 有时合并更新对象传入有时不合并更新函数传入 第一个参数是函数的时候不会合并更新每次调用的时候可以依赖于上一个setState的值但是还是异步更新。 setState更新的数据回调函数 这里的回调函数类似与vue中的nextTick回调函数可以拿到最新的state值在下一个宏任务最开始运行。 2- React 高级特性 2-1高阶组件公共逻辑代码的抽离minin已经弃用 本质为一个函数采用装饰设计模式接收一个基础组件输出一个增强后的组件实现组件状态的复用。如果已经props穿透可以多层嵌套。 // 基础组件 class Base extends React.Component{state {money:0}render(){return divh1 我是Base组件 - 我有{ this.props.money || this.state.money}/div/div} }// 高阶组件HOC function WithMoney (Base){class AddMoney extends React.Component{state {money:1000}render(){return Base {...this.props} {...this.state} /Base}} renturn AddMoney }//增强后Base组件 const BaseWithMoney WithMoney(Base) 2-2 render - props 公共逻辑代码的抽离mixin已经弃用 定制一个组件在这个组件里面完成一部分功能逻辑/ui而另外一个组件需要这个功能的时候将公共组件作为父组件/子组件传递/接收对方的功能。 //功能组件class AddMoney extends React.Component{state {money:1000}render(){return this.props.children(this.state.money)}} //样式组件 class Base extends React.Component{state {money:0}render(){return divh1 我是Base组件 - 我有{ this.props.money || this.state.money}/div/div} }//展示组件 class Home extends React.Component{render(){return divMoney(data)Base {...data}//Money/div} }2-3 Portals 传送门 在不改变组件嵌套的结构情况下实现自定义该组件在哪个节点渲染 class Base extends React.Component{state {money:0}render(){return divh1 我是Base组件 - 我有{ this.props.money || this.state.money}/div/div} } //该组件在文档自定义位置渲染即使渲染位置变了但是和父组件的练习没有改变事件冒泡也能实现 export default ReactDOM.CreateProtals(Base/,document.文档任意节点2-4 异步组件 业务中的一些大组件不一定会被使用如果同步加载首屏加载时间延长而且或许这个大组件根本用不到。 React中通过React.lazy达到异步加载组件的效果使用React.suspense优化加载过程 //引入BigDemo组件 const BigDemo React.lazy(()import(组件地址))//加载大组件时展示的数据 React.suspense fallback { div Loading...../div}BigDemo / /React.suspense 2-5 性能优化 代码层面优化 减轻state数据非更新视图的数据不需要放在state中 优化state的数据结构避免多层嵌套复杂数据类型 避免子组件的不必要更新 shouldComponentUpdate( nextprops,nextstate) 可以获取最新的props和state和旧值作比较若一样则该组件不更新 使用纯组件类组件 内部自动浅层次比较新旧值 React.memo(函数组件比较函数 ) 多使用不可变值 immutable.js,让数据彻底成为不可变量。 基于数据共享速度快能达到深拷贝效果 长列表性能优化 事件的销毁 图片资源懒加载 路由懒加载 第三方插件的按需引入 优化无限列表性能 服务端渲染 SSR or 预渲染 Webpack 层面的优化 Webpack 对图片进行压缩减少 ES6 转为 ES5 的冗余代码提取公共代码模板预编译提取组件的 CSS优化 SourceMap构建结果输出分析React项目的编译优化production自动开启代码优化、混淆、压缩 Web 技术的优化 在服务端开启 gzip 压缩浏览器缓存CDN 的使用使用 Chrome Performance 查找性能瓶颈 2-6 组件懒加载 1.代码分割 import // 引入一个组件 import {add } from ./math// 异步引入组件 // 触发import函数时才异步导入 import(./math).then((math) {math.add() })当webpack解析到这个语法的时候自动进行代码分割。 2.React.lazy() Suspense // 异步引入组件 //使用MyErrorBoundary包裹更容易兼容错误 MyErrorBoundary//使用suspense组件包裹更好的兼容等待页面Suspense fallback{divLoading.../div}//在组件首次渲染的时候自动导入const Component React.lazy((){import(./math)})/Suspense /MyErrorBoundary3- React 核心原理 3-1函数式编程 一种编程范式主要特征是使用纯函数和不可变量来实现数据驱动视图效果 纯函数接收一个值输出一个值不产生其他副作用不可变量数据不能通过操作自身进行数据改变setState设置的值只能是一个新值原来的数据永远不能改变。 3-2 JSX编译 jsx转译成React.creatElement函数得到react元素render函数执行得到vnode描述dom节点的js对象通过path函数渲染 3-3 组件渲染过程 和 更新过程 渲染阶段 通过props/state获得数据render函数直接生成vnodepatch函数接收vnode渲染 更新阶段 setsStatenewvaluerender根据newvalue得到newvnodepatch函数阶段一得到vnode。执行diff算法得到操作dom最少的更新方式patch函数阶段二将计算结果渲染到视图 **patch阶段的问题**组件在更新阶段计算和视图渲染都十分消耗性能如果此时还有其他复杂dom操作动画拖拽cpu压力很大很有可能卡顿。 **fiber机制**将patch第一阶段进行任务拆分。通过window.requestIndleCallback监听到dom是否更新dom需要更新的时候暂停diff算法。 3-4 合成事件机制 特点 所有的事件挂载到document中event事件对象不是原生的是合成事件机制SyntheticEvent函数合成的事件对象。event.nativeEvent可以访问到原生的事件对象和vue与原生的事件不同 处理流程 点击按钮触发事件冒泡到documentdocument挂载了React中的所有事件通过合成事件函数生成合成事件触发对应的事件处理函数 作用 React内部实现一套自己的事件处理逻辑更好的兼容性和跨平台事件统一的挂载到document减少内存消耗解绑事件方便方便事件的统一管理 3-5 setState 和 batchUpdate机制 setState执行流程 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mBtei24i-1598189226405)(C:\Users\ADMINI~1\AppData\Local\Temp\1591758044422.png)] 在React内部采用transaction事务机制 每个挂载在React中的函数在执行前入口和执行结束出口都会执行一套处理逻辑在挂载函数执行前调用isBatchUpdate true在挂载函数执行结束后调用isBatchUpdate false而在timeout和自定义事件回调函数执行的时候isBathchUpdate已经是false所以同步更新 面 - React和vue对比 相同 都采用组件化都是数据驱动视图都使用vdom操作dom都通过props传递数据 使用方式不同 React使用Jsx拥抱js体验vue采用模板拥抱html体验 React是函数式编程vue式声明式编程 React只提供框架和核心驱动vue封装了很多操作 React讲究状态不可变vue提倡状态可变 webpack知识点 1. 什么是webpackwebpack的运行原理如何打包 字节跳动 webpack是一个打包模块化javascript的工具在webpack里一切文件皆模块通过loader转换文件通过plugin注入钩子最后输出由多个模块组合成的文件webpack专注构建模块化项目。 WebPack可以看做是模块打包机它做的事情是分析你的项目结构找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言ScssTypeScript等并将其打包为合适的格式以供浏览器使用。 2.什么是bundle,什么是chunk什么是module? bundle是由webpack打包出来的最终的文件chunk代码块一个chunk由多个模块组合而成用于代码的合并和分割module是开发中的单个模块在webpack的世界一切皆模块一个模块对应一个文件webpack会从配置的entry中递归开始找出所有依赖的模块 3.什么是Loader?什么是Plugin? loader Loader直译为加载器。Webpack将一切文件视为模块但是webpack原生是只能解析js文件如果想将其他文件也打包的话就会用到loader。 Loaders是用来告诉webpack如何转化处理某一类型的文件并且引入到打包出的文件中 Plugin Plugin直译为插件。Plugin可以扩展webpack的功能让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件Plugin 可以监听这些事件在合适的时机通过 Webpack 提供的 API 改变输出结果。 4. 有哪些常见的Loader他们是解决什么问题的 file-loader把文件输出到一个文件夹中在代码中通过相对 URL 去引用输出的文件url-loader和 file-loader 类似但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去source-map-loader加载额外的 Source Map 文件以方便断点调试image-loader加载并且压缩图片文件babel-loader把 ES6 转换成 ES5css-loader加载 CSS支持模块化、压缩、文件导入等特性style-loader把 CSS 代码注入到 JavaScript 中通过 DOM 操作去加载 CSS。eslint-loader通过 ESLint 检查 JavaScript 代码 5. 有哪些常见的Plugin define-plugin定义环境变量html-webpack-plugin简化html文件创建uglifyjs-webpack-plugin通过UglifyES压缩ES6代码webpack-parallel-uglify-plugin: 多核压缩,提高压缩速度webpack-bundle-analyzer: 可视化webpack输出文件的体积mini-css-extract-plugin: CSS提取到单独的文件中,支持按需加载 6.webpack的构建流程是什么?从读取配置到输出文件这个过程尽量说全 Webpack 的运行流程是一个串行的过程从启动到结束会依次执行以下流程 初始化参数从配置文件和 Shell 语句中读取与合并参数得出最终的参数开始编译用上一步得到的参数初始化 Compiler 对象加载所有配置的插件执行对象的 run 方法开始执行编译确定入口根据配置中的 entry 找出所有的入口文件编译模块从入口文件出发调用所有配置的 Loader 对模块进行翻译再找出该模块依赖的模块再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理完成模块编译在经过第4步使用 Loader 翻译完所有模块后得到了每个模块被翻译后的最终内容以及它们之间的依赖关系输出资源根据入口和模块之间的依赖关系组装成一个个包含多个模块的 Chunk再把每个 Chunk 转换成一个单独的文件加入到输出列表这步是可以修改输出内容的最后机会输出完成在确定好输出内容后根据配置确定输出的路径和文件名把文件内容写入到文件系统。 7.如何利用webpack来优化前端性能 压缩代码。删除多余的代码、注释、简化代码的写法等等方式。可以利用webpack的UglifyJsPlugin和ParallelUglifyPlugin来压缩JS文件 利用cssnanocss-loader?minimize来压缩css 利用CDN加速。在构建过程中将引用的静态资源路径修改为CDN上对应的路径。可以利用webpack对于output参数和各loader的publicPath参数来修改资源路径 删除死代码Tree Shaking。将代码中永远不会走到的片段删除掉。可以通过在启动webpack时追加参数–optimize-minimize来实现 提取公共代码。将代码切片分组公共代码更容易命中缓存 懒加载 将代码进行代码分割一般都是分割需要懒加载的组件或者公共代码。然后组件加载方式为懒加载再加载该组件 小图片编译成base64码 bundle命名加hash值若文件内容不变则可以命中缓存 使用production模式打包内置了很多优化代码的配置tree-sharking。es6引入时执行前静态编译 scope Hosting打包时减少打包产生的作用域 8. 如何提高webpack的打包速度? 多进程打包压缩代码忽视打包项提前打包常用大型静态文件避免担反复编译利用缓存缩小编译搜索范围 happypack插件和ParallelUglifyPlugin插件: 多进程打包和多进程压缩代码还可以利用hash缓存避免重复不必要操作IgnorePlugin和nopare都可以忽视一些没必要打包项dll: 采用webpack的 DllPlugin 和 DllReferencePlugin 引入dll让一些基本不会改动的代码先打包成静态资源,避免反复编译浪费时间利用缓存: webpack.cache、babel-loader.cacheDirectory、HappyPack.cache都可以利用缓存提高rebuild效率缩小文件搜索范围: 比如babel-loader插件,如果你的文件仅存在于src中,那么可以include: path.resolve(__dirname, ‘src’),当然绝大多数情况下这种操作的提升有限,除非不小心build了node_modules文件 9. 介绍模块化发展历程 模块化主要是用来抽离公共代码隔离作用域避免变量冲突等。 IIFE 使用自执行函数来编写模块化特点在一个单独的函数作用域中执行代码避免变量冲突。AMD 使用requireJS 来编写模块化特点依赖必须提前声明好。CMD 使用seaJS 来编写模块化特点支持动态引入依赖文件。CommonJS nodejs 中自带的模块化。UMD兼容AMDCommonJS 模块化语法。webpack(require.ensure)webpack 2.x 版本中的代码分割。ES Modules ES6 引入的模块化支持import 来引入另一个 js 。 10.webpack 热更新原理 自动刷新是整个网页刷新状态丢失 热更新新代码生效网页不刷新状态不丢失 热更新是使用了HMR插件我没有仔细研究原理但是猜测是监听了系统对这部分文件的保存操作的监听然后执行更新而插件内保存了网页的状态。 11-介绍一下babel babel是一款JavaScript语言的编译器他能将高es版本的语言规范转换成低版本。当然高版本一些类似于promise等新增的低版本语言无法替换的新语法是无法转换的 babel 的处理流程 词法解析将字符串形式的代码转换成Tokens。语法解析解析器会把tokens转换成抽象语法树AST核心数据结构遍历AST并应用AST转换器增删改查AST节点访问者模式-深度优先的查找原则。根据新AST树生成新代码 babel架构 访问者会以深度优先的顺序, 或者说递归地对 AST 进行遍历其调用顺序如下图所示: 上图中绿线表示进入该节点红线表示离开该节点。 NODEJS知识点 nodejs是一个基于v8引擎的js的运行环境标准的模块化开发环境所有功能模块按需导入。 服务器返回html文档的过程 服务器收到请求解析url了解请求数据找到html文件解析html文件成字符串格式发送给客户端 1.模块分类 global模块除了global模块其他模块都要引入 在任何地方都能调用 path模块 用于操作路径解决路径的兼容问题 fs模块 操作文件 http模块 创建一个服务器监听请求响应设置端口启动服务器 art-template 模块 用于后台渲染 url模块 解析url地址 mysql模块 操作数据库 2.node模块类型 核心模块:随着node一起安装第三方模块下载引入的自定义模块自己创建的 3-中间件 项目架构中保护后端的一种手段用户只能访问中间件中间件访问服务器。 中间件会辅助服务器处理部分请求多个中间件串联使用通过next进入下一个中间件处理功能 4-node事件循环机制 和 浏览器的事件循环机制 4-1 浏览器的事件循环机制 浏览器是多进程的 主进程创建和销毁其他进程GPU进程第三方插件进程浏览器内核渲染进程每打开一个窗口就会创建一个 浏览器渲染进程包含多个线程 GUI渲染进程浏览器界面渲染js引擎线程 ------------主 线程 ----事件触发线程定时器触发线程 ----- 宏任务异步请求线程 当浏览器js引擎这个主线程执行一段代码的时候会遇到一些异步操作就会把该任务交给相对应的线程来处理主线程继续执行自己的代码任务主线程和定时器线程做的任务称为宏任务 ui渲染/主代码/定时器。若在宏任务期间一些工作线程的任务完成了这些任务称之为微任务promisenexttick事件回调 那么主线程在进入下一个tick之前会将这次tick产生的微任务执行玩。 这就是浏览器的执行机制。 node是单线程程序通过异步i/O解决阻塞问题更高效的使用cpu node的事件循环机制和浏览器的其实很类似都是工作线程配合主线程来进行执行代码。只不过node是在线程池中处理异步任务。但是由于线程池的原因导致node执行微任务的时机和浏览器相比略有差别 浏览器环境下microtask 的任务队列是每个 macrotask 执行完之后执行。而在 Node.js 中microtask 会在事件循环的各个阶段之间执行也就是一个宏任务中的六个阶段中的一个阶段执行完毕就会去执行 microtask 队列的任务。 node和浏览器的事件循环机制大致逻辑是一样的只是node的工作线程更为复杂不同的线程之间还有执行优先级。 小程序 wechat运行在客户端系统小程序运行在wechat上h5的升级优化版。 面 - 小程序开发和vue开发的区别#$ 小程序开发和vue开发十分类似都是将一个组件的样式结构数据插槽而且都可以引入了指令都是js统一管理。但是在数据驱动和生命周期上面区别挺大。 vue直接通过mvvm将数据和视图双向绑定讲究可变值且数据一变视图立马更新。但是小程序不一样小程序要想数据改变视图里面改变就要通过调用setdata方法来调用 小程序真的很简单官方给小程序给了很多限定同时给给开发者很多便利。官方标签也就几个还使用数据驱动视图。小程序页面和功能本来就简单而且微信提供的接口多。小程序开发很简单的。但凡会一点vue的开发者。看几天文档就会了。 编程范式 编程式 - 手动通过js指令操作dom声明式 - 通过操作数据后台根据数据帮你操作dom 1-文件架构 APP APP.js全局入口文件APP.json 全局配置文件APP.wxss 全局样式文件 每个组件 .WXS 存储数据和生命周期函数 WXS和js代码差不多只是能够在WXML中运行WXS脚本而已.json 存储配置.WXML.WXSS 2- 双线程模型 渲染层线程js层线程 通过阻塞和等待响应来配合 3- 小程序执行流程 启动小程序解析APP.json注册APP 执行APP组件生命周期 加载注册自定义组件 加载组件json文件渲染层加载渲染结构文件逻辑层加载js文件 执行生命周期 浏览器输入url后发生了什么网络 / 浏览器 ​ 这是一个好问题其实细究起来里面的内容挺深的里面涉及的内容很多。我试着把它讲清楚 基本流程 1.DNS地址查询 2.TCP连接 3.发送HTTP请求 4.服务器处理请求以及响应 5.浏览器根据响应渲染页面 6.tcp连接结束 1-DNS地址查询 1.1什么是DNS ​ DNS全程是 Domain Name System 域名系统服务协议。 我们访问服务器时其实访问的是该服务器的ip地址但是ip地址很难记忆考虑到访问的便捷性就提出了DNS。DNS其实就是一个翻译的功能吧。他可以把网址翻译成对应的ip地址我们就可以通过得到的ip地址访问了。 1-2 DNS查询 ​ 他的查询是一种是一层层查询的 查询浏览器缓存 ​ 从html5过后浏览器的缓存就用的越来越多了这时候呢如果浏览器缓存中有对应的ip地址整个过程就结束了。 ​ 不过因为浏览器的缓存机制比如浏览器的缓存大小和缓存时间的限制都会导致DNS解析失败。 查询系统的缓存 ​ 如果在系统的hosts文件里面设置了DNS映射。也可以完成域名解析。 ​ 不过如果本地hosts文件被恶意修改就会访问到修改后的ip地址造成域名劫持。 查找路由器的缓存 一般一些路由器也会缓存DNS 查找本地 DNS缓存服务器 根据网络配置中的DNS服务器地址访问本地区的域名服务器。这个域名服务器缓存了大量的域名解析的结果虽然也有时间控制。基本域名解析到这里可以完成。 递归查询DNS服务器 本地DN服务器会将查询域名的顶级域名服务器的IP地址返回到本地DNS 比如com 本地DNS服务器再向顶级域发送请求返回二级域的ip地址 比如baidu 然后依次递归查询直到得到最终的查询结果将得到的ip地址返回本机 ​ 1-3 DNS中的安全问题 DNS欺骗 就是诱导用户去访问一个指定的ip地址 常见的就是缓存遭到了恶意修改。本机上的hosts文件呐或者本地DNS服务器。可能造成的结果就是信息泄露啊。 对本地DNS服务器进行拒绝服务攻击 让本地DNS拒绝接受查询请求的服务结果就是无法上网 而且攻击DNS服务器的手段还挺多 1-4 DNS中的网络性能优化 1-减少DNS的查找次数减少CDN的重定向负载均衡 ​ 服务器资源是分布式的DNS可以就近返回一个服务器ip地址这就是负载均衡和DNS重定向 ​ CDN 内容分发网络 ​ 在各个地区建立缓存服务器浏览器发送数据请求的时候经过算法会经过延迟最低的堵塞最低的网路访问最近的服务器。而若该服务器没有请求需要的内容就会发送回源。去往上一层服务器查找 ​ 虎牙和阿里云EMS联合 ​ 2-在html的meta标签和link标签告诉浏览器对该页面做预解析 用meta信息来告知浏览器, 当前页面要做DNS预解析: meta http-equivx-dns-prefetch-control contenton /在页面header中使用link标签来强制对DNS预解析: link reldns-prefetch hrefhttp://bdimg.share.baidu.com /2-TCP连接 2-1什么是tcp ​ tcp是一种可靠的数据传输协议.在网络传输中属于传输层面。 ​ 传输时候包裹了http报文数据被ip报文包裹。 ​ 数据建立连接时候通过标识位ACKFINSYN等和对方计算机控制数据传输进程。 2-2 三次握手和四次挥手 1.三次握手 客户端发送SYN表示要和服务器建立连接同时带上ISN序列号 SYN 客户端序列号 服务器返回ACK客户端序列号1表示以及收到SYN同时发送SYN加上自己的序列号 ACK客户端序列号1服务端序列号 客户端发送ACK确认收到对方的回复 ACK服务端序列号1 2.为什么要三次握手 确认双方都都能数据传输 tcp是双向传输的协议首先是确保双方都能接受和发送数据第一次握手表示发送方能够发送数据第二次握手ACK代表接受放能够收受数据SYN确保接收方能够发送数据。第三次握手确保发送方能够接受数据经过三次握手就能确定双方都有接受和发送的功能就没必要四次两次就实现不了了 握手的次要目的是告知和协商一些信息**** MSS–最大传输包SACK_PERM–是否支持Selective ack(用户优化重传效率WS–窗口计算指数有点复杂的话先不用管 3.四次握手 客户端主动关闭的一方发送FIN表示单方面要关闭数据的传输服务端接收到FIN后返回一个ACK表示收到等到服务器的数据全部发送完成也发送一个FIN。表示关闭数据传输客户端回复ACK表示确认 4.为什么要四次挥手 TCP是双向传输的所以结束首先要确保双方都关闭了数据传输端口同时TCP是支持半关闭的一方结束发送但是能够接收数据因此接受和发送都要关闭而且收到对方的关闭信息还要确认回复第一次客户端发送关闭发送数据的FIN表示自己没有数据要传送了第二次服务器表示收到客户端进入等待状态但是还需要继续发送数据给对方不能马上回复FIN第三次服务端发送数据全部发送完成的FIN表示发送完全部数据进入确定状态第四次客户端回复ACK表示收到服务端收到ACK后里立马关闭传输接口。客户端则是处于等待若短时间内没有再次收到服务端的FIN则表示ACK以及送达客户端关闭接口 5超时和重传 ​ 数据在传输时存在一个数据丢失和网络拥堵问题。发送方在发送数据时候会启动一个计时器如果在一定时间内没有收到对方的接受确定。会重新发送一份数据。如果接收方收到了两份相同的数据会根据编号删除一份数据 ​ 但是超时重传会让本就拥堵的网络更加拥堵 6-tcp的可靠性如何保证 分块传送数据被分割成最合适的数据块UDP的数据报长度不变等待确认通过定时器等待接收端发送确认请求收不到确认则重发确认回复收到确认后发送确认回复(不是立即发送通常推迟几分之一秒)数据校验保持首部和数据的校验和检测数据传输过程有无变化乱序排序接收端能重排序数据以正确的顺序交给应用端重复丢弃接收端能丢弃重复的数据包流量缓冲两端有固定大小的缓冲区滑动窗口防止速度不匹配丢数据 3-发送HTTP请求 3-1.什么是HTTP协议 ​ 数据传输的规范 ​ Web使用一种名为HTTPHyperText Transfer Protocol超文本传输协议的协议作为规范完成从客户端到服务器等一系列运作流程。而协议是指规则的约定。可以说Web是建立在HTTP协议上通信的。 3-2.HTTP连接方式 串行连接 每次一个请求都要经过请求连接请求响应结束连接。反应速度特别慢容易达到浏览器的请求上限 持久连接 keep-alive模式 http 1.0中默认是关闭的需要在http头加入Connection: Keep-Alive”才能启用Keep-Alivehttp 1.1中默认启用Keep-Alive如果加入Connection: close “才关闭。目前大部分浏览器都是用http1.1协议也就是说默认都会发起Keep-Alive的连接请求了所以是否能完成一个完整的Keep- Alive连接就看服务器设置情况。 建立连接后的一段时间可以进行多次请求。http1.1协议基本都是持久连接。但是由于一个请求结束才能进行下一个请求容易造成请求堵塞 管道化持久连接 可以同时进行多次请求 HTTP 2.0多路复用 WebSocket 3-3.HTTP报文 1-报文格式 请求行 请求方法协议版本 请求头部 请求URI客户端信息请求配置信息 请求体 用户信息数据信息 响应行 协议版本状态码 响应头部 请求服务器信息资源配置信息 响应体 返回的资源 2-请求方式 GET - 获取服务器资源 POST - 信息传输 PUT -文件传输 DELETE - 删除文件 HEAD - 获取报文首部 3-常见的状态码 ​ 1-1XX 大多数表示请求收到还在处理 ​ 100 继续发送请求 ​ 101需要切换HTTP协议。 ​ 2-2XX 请求已经被接受理解 ​ 200成功返回数据 ​ 201请求成功请求想要的资源已经创建 ​ 202 ​ 3-3XX 需要客户端进行下一步操作才能完成一般为重定向 ​ 304页面需要重定向 ​ 4- 4XX ​ 客户端发生错误导致服务器的处理。服务器一般会返回一个错误说明 ​ 400语法错误服务器理解不了常见表单验证 ​ 401 寻求用户的授权信息 ​ 402 服务里理解请求但是拒绝执行 ​ 404 服务器上并没有请求需要的资源 ​ 5- 5XX 服务器端 发生异常 ​ 500 后台代码出错 ​ 502 代理服务器出错 3-4-HTTP版本 ​ http1.1 比较 http1.0 ​ 缓存处理的方式更多 ​ 带宽和网络优化 ​ 错误通知的管理 ​ Host管理 ​ 长连接 ​ HTTP的版本更新只是在TCP连接等上面做了一系列优化但是本质没有改变。他本质上还是让数据传输处明文传输的的状态。 信息可能被窃听使用抓包工具 无法知道通信双方是谁可能遭遇伪装 信息可能被中间人篡改无法保证报文的完整性 3-5-HTTPS 1.什么是HTTPS 对数据进行加密建立一个安全的信息通道保证传输过程中的数据安全对网站服务器进行真实身份验证 HTTPS是在THTTP基础上建立SSL加密层并且对传输的数据进行加密能确认数据传输双方信息的HTTP协议升级版 优势 数据隐私性内容经过对称加密每个连接生成唯一一个加密密钥数据完整性内容的传输经过完整性校验身份认证第三方无法伪造客户端服务端身份 利于seo 劣势 加密消耗CPU性能和内存证书使用起来费时费钱 2- HTTPS功能实现 ​ https实际上只是披上SSL协议的HTTP协议通过SSL协议的优势弥补HTTP协议的缺陷。 1.内容被窃听问题 - 加密 ​ 方法一对称性加密 ​ 这种加密方式的解密和加密都是用同一套密钥。问题在于如何安全的将对称加密的密钥发给对象让对方能够解密信息。 ​ ​ 方式二非对称加密 ​ 发送方有两套密钥将公开密钥发送给接收方接收方通过公开密钥加密数据将信息返回。发送方又用私密密钥解锁数据。但是加密解密时间太长 ​ 公钥加密的内容只有私钥可以解开私钥加密的内容所有的公钥都可以解开当然是指和秘钥是一对的公钥 ​ 方式三对称加密非对称加密 ​ 发送方通过对称加密将数据进行加密。然后通过对方的非对称加密的公开密钥加密对称加密的密钥。然后将发送数据和密钥。 ​ 中间人能够劫持公钥伪造假公钥发送 2.报文被篡改 - 数字签名 ​ 网络传输要经过很多的中间节点数据虽然无法被解密但是很有可能被篡改。 ​ 数字签名作用 能确定消息确实是由发送方签名并发出来的因为别人假冒不了发送方的签名。数字签名能确定消息的完整性,证明数据是否未被篡改过。 ​ 发送者通过哈希函数将一段文本转成消息摘要再通过私钥加密成数字签名将数字签名和文本原文发送。接收者解密数字签名生成消息摘要1用哈希函数处理文本得到消息摘要2对比两个消息摘要来确保信息的完整性。 3-通信方身份伪装 - 数字证书 数字证书认证机构通过服务端提供的信息进行认证发布加密后的证书文件客户端发送请求时服务端返回数字证书文件。客户端解密检查数字证书的信息。 3-4-带宽和延迟 影响一个 HTTP 网络请求的因素主要有两个带宽和延迟。 **带宽**如果说我们还停留在拨号上网的阶段带宽可能会成为一个比较严重影响请求的问题但是现在网络基础建设已经使得带宽得到极大的提升我们不再会担心由带宽而影响网速那么就只剩下延迟了。延迟 浏览器阻塞HOL blocking浏览器会因为一些原因阻塞请求。浏览器对于同一个域名同时只能有 4 个连接这个根据浏览器内核不同可能会有所差异超过浏览器最大连接数限制后续请求就会被阻塞。DNS 查询DNS Lookup浏览器需要知道目标服务器的 IP 才能建立连接。将域名解析为 IP 的这个系统就是 DNS。这个通常可以利用DNS缓存结果来达到减少这个时间的目的。建立连接Initial connectionHTTP 是基于 TCP 协议的浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文达到真正的建立连接但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显慢启动则对文件类大请求影响较大。 4- 浏览器渲染页面 ​ 浏览器收到服务器返回的资源数据后将资源渲染到浏览器窗口。主要功能就是向服务器发送请求在浏览器窗口展示返回的网络资源。能够解析的资源必须符合W3C的规定其他资源需要配置插件 4-1浏览器组成 用户界面地址栏等除去主窗口以外的部分浏览器引擎在用户界面与渲染引擎之间传输指令渲染引擎展示请求的资源内容网络负责网络调用用户界面后端js引擎执行js代码数据存储持久层 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KNhsXWKD-1598189226416)(C:\Users\Administrator\Desktop\layers.png)] 4-2 浏览器如何解析资源渲染页面 ​ 浏览器解析资源是一个边解析边渲染的过程。主要通过渲染引擎和js引擎来处理网络资源 ​ 1.渲染引擎将html和css文档解析成语法树 ​ 将文档解析成有意义的结构让浏览器能够使用 ​ 阶段一词法分析 ​ 将文档输出解析成token单元 ​ 阶段二语法分析 ​ 生成语法树 ​ 阶段三将语法树编译成机器语言 2.渲染引擎将css语法树和html语法树结合成渲染树 3.渲染引擎和js引擎 ​ 当解析html文档遇到4.触发浏览器的paint事件根据渲染树计算元素位置绘制 ​ DOM节点中的各个元素都是以盒模型的形式存在这些都需要浏览器去计算其位置和大小等这个过程称为回流;当盒模型的位置,大小以及其他属性如颜色,字体,等确定下来之后浏览器便开始绘制内容这个过程称为重绘。页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的尤其是在移动设备上它会破坏用户体验有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。 5.回流和重绘 ​ 回流浏览器在进行布局操作进行位置计算的时候发生 ​ 重绘浏览器根据属性渲染页面 ​ 回流一定重绘 优化 1、浏览器自己的优化浏览器会维护1个队列把所有会引起回流、重绘的操作放入这个队列等队列中的操作到了一定的数量或者到了一定的时间间隔浏览器就会flush队列进行一个批处理。这样就会让多次的回流、重绘变成一次回流重绘。 2、我们要注意的优化我们要减少重绘和重排就是要减少对渲染树的操作则我们可以合并多次的DOM和样式的修改。并减少对style样式的请求。 **浏览器缓存 不过浏览器发送请求还有一种情况就是http缓存也叫浏览器缓存。 浏览器和服务器通信的方式为应答模式浏览器发送http请求 - 服务器响应该请求。 浏览器会根据第一次向浏览器发送请求后拿到的响应报文的响应头中的缓存标识来决定是否缓存结果命中则将请求结果存入浏览器缓存中 浏览器下一次发送请求会查看浏览器缓存有没有缓存此次请求的缓存结果 强缓存 浏览器的缓存数据直接能够使用 协商缓存 浏览器的数据不确定是否可用 当浏览器查看浏览器缓存时会发生几种情况 不存在缓存结果和缓存标识强缓存失效直接向服务器发送请求存在该缓存结果和缓存标识但是此结果超过规定的时间限制已经失效浏览器缓存返回缓存标识携带缓存标识向浏览器发送请求确认此缓存是否可用。 缓存能用返回304使用缓存缓存不能用返回200使用新数据 浏览器离线缓存 HTML5提出的一个新的特性离线存储。通过离线存储我们可以通过把需要离线存储在本地的文件列在一个manifest配置文件中这样即使在离线的情况下用户也可以正常看见网页。 ajax请求和跨域问题 1- get 请求和get 请求的区别 get和post请求只是两种不同的传送请求的类型底层都是tcp/ip协议。 get请求的数据放在请求行中post放在请求体中get发送请求的时候会将请求头和包含数据的请求行直接一起发送出去post发送请求时会先发送请求头和请求行间隔一段时间才会发送包含数据的请求体网络好的时候两者请求事件相差不大网络差的时候post文件更不容易丢失get发送请求的数据有格式和大小4k的限制post则没有限制get请求参数会保留在浏览器历史记录post不会 2- 网络传输常用的数据格式 xml和json xml 可拓展标记语言能够传输数据 json js对象标记轻量级数据交换格式本质上时特殊格式的字符串包含了js的数据。 由于对象等一些属性并不能通过网络传输只能借助转成json格式的方式传输使用时再转成对象数据模式。 json.stringfy(js数据) json.parse(json字符串) 3- formdata 对象 以二进制的方式管理表单数据用post方式可以发送大体积文件。 可以通过xhr自带的方法监听上传和下载进度 4- 跨域 / 同源 同源两个网站来自同一个服务器 域名相同端口相同协议相同 跨域不同源网站则跨域 不能共享cookie不能相互操作dom不能互相发送qjax请求 解决跨域 CORS 通过请求头和响应头来实现跨域资源访问请求头中包含了请求来源的信息若服务器同意访问就可以在响应头中设置相对于的数据 简单支持各种传输类型要对服务端接口进行改造 JSONP 在html中一些标签的资源请求不受同源策略的限制。比如script标签。这时候就可以哦那个过script标签的src属性发送请求获得响应。 兼容性好只支持get请求且安全性极低 正向代理 / 反向代理 委托能访问目标网站的中间服务器代为发送和接收数据 v8引擎的内存控制 v8使用的内存是有限制的而进程需要内存时才会一点点给他。 垃圾回收机制 **分代式回收机制**按照对象的存活时间将对象划在分代空间老生代和新生代空间采用不同的算法处理数据。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7RxfMltW-1598189226423)(C:\Users\ADMINI~1\AppData\Local\Temp\1592199080930.png)] 倘若老生代空间的对象长时间没办法被回收就造成了内存泄漏。 service worker 是独立于js线程的一个异步线程不能访问dom和全局变量他有着自己的全局作用域。可以用于存储和处理数据多用于pwa渐进式webapp 性能优化 页面初始阶段加载慢一般是资源加载过多过大减少资源数量和资源大小 通过懒加载的方式来处理非首屏的图片和组件 小图标使用iconfont 小图片直接使用base64编码置于html文档中等方式来实现资源合并 使用缓存和cdn来减少请求的时间和次数 cssjs文件混淆压缩 图片压缩 在服务端开启gzip进行全部文件压缩 production模式自动内置优化混淆压缩 多命中缓存 减少网络请求 价绍资源体积 减少访问次数 用cdn 懒加载 防抖节流 WEB安全 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EOq4WwiW-1598189226424)(C:\Users\ADMINI~1\AppData\Local\Temp\1592382907762.png)] 1.xss攻击 1-1 xss介绍 ​ 跨站脚本攻击简称XSS。是一种代码注入攻击。攻击者在目标网站注入恶意脚本让他在浏览器运行即可获得用户信息。 ​ XSS 的本质是恶意代码未经过滤与网站正常的代码混在一起浏览器无法分辨哪些脚本是可信的导致恶意脚本被执行。 ​ 而由于直接在用户的终端执行恶意代码能够直接获取用户的信息或者利用这些信息冒充用户向网站发起攻击者定义的请求。 ​ 在部分情况下由于输入的限制注入的恶意脚本比较短。但可以通过引入外部的脚本并由浏览器执行来完成比较复杂的攻击策略。 1-2 恶意代码注入方式 用户的ugc信息表单提交第三方链接URL参数POST参数cookierefere 1-3 XSS攻击分类 存储型 存储型 XSS 的攻击步骤 攻击者将恶意代码通过提交放置到目标网站的数据库中。用户打开目标网站恶意代码也从数据库中提取出来拼接到HTML中返回到浏览器。浏览器解析恶意代码。恶意代码窃取用户信息冒充用户进行操作 这种攻击常见于带有用户保存数据的网站功能如论坛发帖、商品评论、用户私信等。 反射型 反射型XSS的攻击步骤 攻击者构造出特殊的url包含恶意代码。 用户打开恶意代码的URL时服务端提取URL中的恶意代码拼接在返回html数据中 用户接收到响应数据开始执行就执行到了恶意代码。 恶意代码窃取用户信息冒充用户进行操作 需要用户主动打开恶意的 URL 才能生效攻击者往往会结合多种手段诱导用户点击常见于网页搜索和跳转。 DOM型 DOM 型 XSS 的攻击步骤 攻击者构造出特殊的 URL其中包含恶意代码。用户打开带有恶意代码的 URL。用户浏览器接收到响应后解析执行前端 JavaScript 取出 URL 中的恶意代码并执行。恶意代码窃取用户数据并发送到攻击者的网站或者冒充用户的行为调用目标网站接口执行攻击者指定的操作。 DOM 型 XSS 跟前两种 XSS 的区别DOM 型 XSS 攻击中取出和执行恶意代码由浏览器端完成属于前端 JavaScript 自身的安全漏洞而其他两种 XSS 都属于服务端的安全漏洞。 1-4XSS攻击预防 防护两大要素 防止攻击者提交恶意代码 在前端过滤恶意代码。 不可行。攻击者可以绕过前端过滤直接发送请求。过滤后端写入数据库的数据 只能过滤数字邮件地址等明确性的数据。否则会容易由于数据不确定性引起乱码问题。 防止浏览器执行恶意代码主要防护途径 防止 HTML 中出现注入。存储型反射型 方案一纯前端渲染SSR ​ 纯前端渲染的过程 ​ 浏览器先加载一个静态 HTML此 HTML 中不包含任何跟业务相关的数据。 ​ 然后浏览器执行 HTML 中的 JavaScript。 ​ JavaScript 通过 Ajax 加载业务数据调用 DOM API 更新到页面上。 方案二对html进行转义 针对等特殊字符串 防止 JavaScript 执行时执行恶意代码。 dom型避免将不可信的html插入到页面中减少使用innerHTML等方法。 dom的一些事件监听器能够识别字符串当作代码执行。避免传递不可信的数据拼接到字符串传递给这些API。比如onload,onerroe,href属性定时器eval() 表单输入长度控制。 验证码和cookie保护 避免拼接的内联事件。尽量使用事件绑定 避免拼接html框架很大程度减少了攻击 2.CSRF攻击 2-1 CSRF介绍 ​ CSRF 跨站请求伪造 攻击者诱导用户进入第三方网页窃取用户的信息绕过被攻击网站的后台验证来进行某些操作 ​ 流程 : 1. 用户登录网站A保留了登录凭证Cookie 攻击者诱导受害者登录网站 B 。 3. 网站B通过用户浏览器向网站A服务器发送请求自动携带用户的Cookie。 4. 网站A后台认为是用户在发送请求正常执行请求 5. 攻击者借用用户的名义进行操作 2-2 攻击类型 ​ CSRF攻击简单来说就是冒充用户发送请求所以能发送请求的操作都能成为它的攻击途径 GET类型CSRF攻击POST类型CSRF攻击链接请求类型的CSRF攻击前两种情况用户打开页面就会中招这种需要用户额外点击 2-3 CSRF攻击特点 攻击一般由第三方网站发起由于冒充用户被攻击网站无法阻止攻击发生不是窃取用户数据而是借助Cookie冒充用户提交请求可以用任何跨域请求达到攻击效果 2-4 防护策略 ​ 防护策略只能从增强网站的安全性出发因为后台无法识别这种攻击。根据CSRF攻击特点指定的方式有 阻止不明外域的访问 同源检测Samesite Cookie 提交时要求附加本域才能获取信息 CSRF Token双重Cookie 同源检测防护 ​ 通过检测前端请求的Origin Header 和Referer Header来确定请求的来源。检测不到或者不是本域发起的请求直接阻止这次请求 双重Cookie验证 ​ 由于攻击的不能获取Cookie只是冒用所以不能发送双重Cookie 在用户访问网站页面时向请求域名注入一个Cookie内容为随机字符串例如csrfcookiev8g9e4ksfhw。 在前端向后端发起请求时取出Cookie并添加到URL的参数中接上例POST https://www.a.com/comment?csrfcookiev8g9e4ksfhw。 后端接口验证Cookie中的字段与URL参数中的字段是否一致不一致则拒绝。 实行成本低 Token防护 ​ 通过token字段登录网站。网站开发的时候面对请求时手动添加Token而不是浏览器自动添加。在我看来是最有效而简单的操作方式。除非有XSS攻击泄露了XSS那么CSRF很难攻击成功。 Samesite Cookie属性 防止CSRF攻击的办法已经有上面的预防措施。为了从源头上解决这个问题Google起草了一份草案来改进HTTP协议那就是为Set-Cookie响应头新增Samesite属性它用来标明这个 Cookie是个“同站 Cookie”同站Cookie只能作为第一方Cookie不能作为第三方Cookie 2-5 CSRF 测试 ​ CSRFTester是一款CSRF漏洞的测试工具 3.点击劫持攻击 ​ 在WEb页面隐藏了一个透明的iframe元素诱导用户点击进行一些不知名操作 4.后端一些攻击漏洞命令行注入和DDos攻击 ​ DDos攻击不断发送请求让网站响应崩溃 面 - 开发中的数据安全问题 前端的安全问题主要发生在代码的安全问题用户在浏览器操作上的安全问题和网络传输的安全问题 代码的安全问题 规范开发避免使用引起xss攻击的代码警惕使用第三方提供的页面组件这些页面组件一般通过iframe方式引入天气等插件。其实这个模块不受我们控制的很容易造成安全隐患。防范本地内存泄漏特别是离线应用和spa页面这些都在本地保存了很多隐私数据此时如果有xss攻击意味着数据全部透明了。可以设置用户离开清除数据、数据加密后保存等方式但是也只是降低了一点风险。还可以通过代码混淆来保护代码吧 网络传输的安全问题 有时候出于性能考虑使用CDN这时候攻击者就可以劫持cdn资源进行不法操作由于http协议的裸奔性任何一个节点的抓包工具都能获取所以更应该使用https协议和token字段 开发项目知识点 yarn 相比于npm的优势 采用多线程下载下载速度更快 yarn更加安全稳定 GIT 项目管理工具 常用的使用指令 git log git reset 回到某个版本号 git branch 创建切换分支 git checkout -b 创建并切换分支 git merge 提交后合并分支 git clone git push git pull [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g0XdhDfL-1598189226425)(C:\Users\ADMINI~1\AppData\Local\Temp\1592400824612.png)] 抓包工具 fiddler linux基本指令 本地登录线上机器SSH 用户名ip地址查看所有文件夹: ll / ls查看隐藏文件夹ll -a查看指令文件ls 文件名创建文件夹 mkdir 文件夹名创建文件 touch 文件名创建并打开文件 vim 文件名删除文件夹 rm -rf 文件夹名前往文件夹 cd重命名文件夹 mv拷贝cp 源文件夹名 ​ 开发流程 需求分析 了解背景需求是否合理需求是否闭环开发难度是否需要其他支持结合小组项目给出排期 技术方案分析 技术求简只要能实现就行写出产出开发文档找准设计重点 开发 排期多流出一点时间符合公司开发规范写开发文档及时写单元测试mock api 模拟数据code review 同事看一下 联调 pm加需求 重新评估排期 测试上线 短信验证码和图片验证码 图片验证码 后台随机生成一串验证码返回给客户端用户输入验证码。发送请求后后台验证用户是否存在以及验证码是否匹配若都验证正确则返回登录成功 短信验证码 输入手机号码提交给后台后台验证手机号码是否注册。通过一套规则生成验证码然后将短信码和手机号给运营平台给用户发送验证码。 后台接收到验证码后检测是否和后台的验证码匹配 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OeXExIQH-1598189226426)(C:\Users\ADMINI~1\AppData\Local\Temp\1592301482820.png)] 移动端的兼容安卓和iOS手机 只有少数情况需要判断操作 基本你就正常写就行 兼容问题自己不常见到 大家记住几个 面试问就说一下 如果面试官说的你不懂我没有遇见这个很正常 兼容问题 有很多版本都不一样 安卓 ios也有不一样 我们遇见了再去百度解决 如果面试 先记住几个 1 怎么判断是安卓还是 ios** //获取浏览器的userAgent,并转化为小写 var ua navigator.userAgent.toLowerCase(); //判断是否是苹果手机是则是true var isIos (ua.indexOf(iphone) ! -1) || (ua.indexOf(ipad) ! -1); if(isIos){做苹果手机兼容 }else{做安卓 }2 兼容问题 1.禁止图片点击放大 部分安卓手机点击图片会放大如需要禁止放大只需要设置css属性 img{ pointer-events: none; } 这个会让img标签的点击事件失效如果想要给图片添加点击事件就要给上面再写一层 2.禁止 iOS 识别长串数字为电话 meta nameformat-detection contenttelephoneno3.禁止复制、选中文本 设置CSS属性 -webkit-user-select:none4.一些情况下对非可点击元素如(label,span监听点击事件不会在IOS下触发css增加cursor:pointer就搞定了 5.上下拉动滚动条时卡顿、慢 body { -webkit-overflow-scrolling: touch; overflow-scrolling: touch; } Android3和iOS5支持CSS3的新属性为overflow-scrolling 6 安卓不会自动播放视频 安卓autoplay没效果 需要手动触发一下 window.addEventListener(touchstart, function(){audio.play(); // 需要主动调用一下js 让视频播放 }, false);7.半透明的遮罩层改为全透明 在ios上当点击一个链接或者通过js绑定了点击事件的元素时会出现一个半透明的背景当手指离开屏幕该灰色背景消失出现“闪屏” html, body {-webkit-tap-highlight-color: rgba(0,0,0,0); }html进行转义** 针对等特殊字符串防止 JavaScript 执行时执行恶意代码。 dom型避免将不可信的html插入到页面中减少使用innerHTML等方法。 dom的一些事件监听器能够识别字符串当作代码执行。避免传递不可信的数据拼接到字符串传递给这些API。比如onload,onerroe,href属性定时器eval() 表单输入长度控制。 验证码和cookie保护 避免拼接的内联事件。尽量使用事件绑定 避免拼接html框架很大程度减少了攻击 2.CSRF攻击 2-1 CSRF介绍 ​ CSRF 跨站请求伪造 攻击者诱导用户进入第三方网页窃取用户的信息绕过被攻击网站的后台验证来进行某些操作 ​ 流程 : 1. 用户登录网站A保留了登录凭证Cookie 攻击者诱导受害者登录网站 B 。 3. 网站B通过用户浏览器向网站A服务器发送请求自动携带用户的Cookie。 4. 网站A后台认为是用户在发送请求正常执行请求 5. 攻击者借用用户的名义进行操作 2-2 攻击类型 ​ CSRF攻击简单来说就是冒充用户发送请求所以能发送请求的操作都能成为它的攻击途径 GET类型CSRF攻击POST类型CSRF攻击链接请求类型的CSRF攻击前两种情况用户打开页面就会中招这种需要用户额外点击 2-3 CSRF攻击特点 攻击一般由第三方网站发起由于冒充用户被攻击网站无法阻止攻击发生不是窃取用户数据而是借助Cookie冒充用户提交请求可以用任何跨域请求达到攻击效果 2-4 防护策略 ​ 防护策略只能从增强网站的安全性出发因为后台无法识别这种攻击。根据CSRF攻击特点指定的方式有 阻止不明外域的访问 同源检测Samesite Cookie 提交时要求附加本域才能获取信息 CSRF Token双重Cookie 同源检测防护 ​ 通过检测前端请求的Origin Header 和Referer Header来确定请求的来源。检测不到或者不是本域发起的请求直接阻止这次请求 双重Cookie验证 ​ 由于攻击的不能获取Cookie只是冒用所以不能发送双重Cookie 在用户访问网站页面时向请求域名注入一个Cookie内容为随机字符串例如csrfcookiev8g9e4ksfhw。 在前端向后端发起请求时取出Cookie并添加到URL的参数中接上例POST https://www.a.com/comment?csrfcookiev8g9e4ksfhw。 后端接口验证Cookie中的字段与URL参数中的字段是否一致不一致则拒绝。 实行成本低 Token防护 ​ 通过token字段登录网站。网站开发的时候面对请求时手动添加Token而不是浏览器自动添加。在我看来是最有效而简单的操作方式。除非有XSS攻击泄露了XSS那么CSRF很难攻击成功。 Samesite Cookie属性 防止CSRF攻击的办法已经有上面的预防措施。为了从源头上解决这个问题Google起草了一份草案来改进HTTP协议那就是为Set-Cookie响应头新增Samesite属性它用来标明这个 Cookie是个“同站 Cookie”同站Cookie只能作为第一方Cookie不能作为第三方Cookie 2-5 CSRF 测试 ​ CSRFTester是一款CSRF漏洞的测试工具 3.点击劫持攻击 ​ 在WEb页面隐藏了一个透明的iframe元素诱导用户点击进行一些不知名操作 4.后端一些攻击漏洞命令行注入和DDos攻击 ​ DDos攻击不断发送请求让网站响应崩溃 面 - 开发中的数据安全问题 前端的安全问题主要发生在代码的安全问题用户在浏览器操作上的安全问题和网络传输的安全问题 代码的安全问题 规范开发避免使用引起xss攻击的代码警惕使用第三方提供的页面组件这些页面组件一般通过iframe方式引入天气等插件。其实这个模块不受我们控制的很容易造成安全隐患。防范本地内存泄漏特别是离线应用和spa页面这些都在本地保存了很多隐私数据此时如果有xss攻击意味着数据全部透明了。可以设置用户离开清除数据、数据加密后保存等方式但是也只是降低了一点风险。还可以通过代码混淆来保护代码吧 网络传输的安全问题 有时候出于性能考虑使用CDN这时候攻击者就可以劫持cdn资源进行不法操作由于http协议的裸奔性任何一个节点的抓包工具都能获取所以更应该使用https协议和token字段 开发项目知识点 yarn 相比于npm的优势 采用多线程下载下载速度更快 yarn更加安全稳定 GIT 项目管理工具 常用的使用指令 git log git reset 回到某个版本号 git branch 创建切换分支 git checkout -b 创建并切换分支 git merge 提交后合并分支 git clone git push git pull [外链图片转存中…(img-g0XdhDfL-1598189226425)] 抓包工具 fiddler linux基本指令 本地登录线上机器SSH 用户名ip地址查看所有文件夹: ll / ls查看隐藏文件夹ll -a查看指令文件ls 文件名创建文件夹 mkdir 文件夹名创建文件 touch 文件名创建并打开文件 vim 文件名删除文件夹 rm -rf 文件夹名前往文件夹 cd重命名文件夹 mv拷贝cp 源文件夹名 ​ 开发流程 需求分析 了解背景需求是否合理需求是否闭环开发难度是否需要其他支持结合小组项目给出排期 技术方案分析 技术求简只要能实现就行写出产出开发文档找准设计重点 开发 排期多流出一点时间符合公司开发规范写开发文档及时写单元测试mock api 模拟数据code review 同事看一下 联调 pm加需求 重新评估排期 测试上线 短信验证码和图片验证码 图片验证码 后台随机生成一串验证码返回给客户端用户输入验证码。发送请求后后台验证用户是否存在以及验证码是否匹配若都验证正确则返回登录成功 短信验证码 输入手机号码提交给后台后台验证手机号码是否注册。通过一套规则生成验证码然后将短信码和手机号给运营平台给用户发送验证码。 后台接收到验证码后检测是否和后台的验证码匹配 [外链图片转存中…(img-OeXExIQH-1598189226426)] 移动端的兼容安卓和iOS手机 只有少数情况需要判断操作 基本你就正常写就行 兼容问题自己不常见到 大家记住几个 面试问就说一下 如果面试官说的你不懂我没有遇见这个很正常 兼容问题 有很多版本都不一样 安卓 ios也有不一样 我们遇见了再去百度解决 如果面试 先记住几个 1 怎么判断是安卓还是 ios** //获取浏览器的userAgent,并转化为小写 var ua navigator.userAgent.toLowerCase(); //判断是否是苹果手机是则是true var isIos (ua.indexOf(iphone) ! -1) || (ua.indexOf(ipad) ! -1); if(isIos){做苹果手机兼容 }else{做安卓 }2 兼容问题 1.禁止图片点击放大 部分安卓手机点击图片会放大如需要禁止放大只需要设置css属性 img{ pointer-events: none; } 这个会让img标签的点击事件失效如果想要给图片添加点击事件就要给上面再写一层 2.禁止 iOS 识别长串数字为电话 meta nameformat-detection contenttelephoneno3.禁止复制、选中文本 设置CSS属性 -webkit-user-select:none4.一些情况下对非可点击元素如(label,span监听点击事件不会在IOS下触发css增加cursor:pointer就搞定了 5.上下拉动滚动条时卡顿、慢 body { -webkit-overflow-scrolling: touch; overflow-scrolling: touch; } Android3和iOS5支持CSS3的新属性为overflow-scrolling 6 安卓不会自动播放视频 安卓autoplay没效果 需要手动触发一下 window.addEventListener(touchstart, function(){audio.play(); // 需要主动调用一下js 让视频播放 }, false);7.半透明的遮罩层改为全透明 在ios上当点击一个链接或者通过js绑定了点击事件的元素时会出现一个半透明的背景当手指离开屏幕该灰色背景消失出现“闪屏” html, body {-webkit-tap-highlight-color: rgba(0,0,0,0); }
http://www.zqtcl.cn/news/951980/

相关文章:

  • 餐饮连锁企业网站建设方案北京软件研发公司
  • 外国网站架构新闻稿
  • 营销网站建设企划案例友情链接怎么添加
  • seo网站搜索优化目前好的推广平台
  • 快速搭建网站页面黄页88网免费发布信息
  • 做网站能赚吗网址大全查询ip地址
  • html5网站正在建设中商城网站系统
  • 室内设计网课北京网站优化前景
  • 北京 网站建设 知乎上海公司买新能源车
  • 成都微网站wordpress 购买
  • 网站开发一般要用到哪些软件软件开发工程师机构
  • dj网站开发建设网站备案 换空间
  • 网站建设哪家最好网站开发怎么报价
  • app 微商城网站建设网站建设流程百科
  • 网站短期培训学校小说网站怎么建设的
  • 最简单的免费网站制作模板电子商务 网站系统
  • 网站域名备案授权书网站建设长春
  • 网站维护主要从哪几个方面做seo营销的概念
  • 北京网站建设营销网站策划案4500
  • 网站建设售后培训wordpress 过滤html
  • 湖北森泰建设集团有限公司网站国外产品设计网站推荐
  • 网站建设与代运营产品介绍排版网页设计教程
  • 音乐网站排名搜索引擎网络推广方法
  • asp.net 企业网站昆明高端seo怎么做
  • 图书馆网站建设需求方案企业网站背景图片
  • 网站app的作用做家教网站资质
  • 资源网站搭建北京app网站建设
  • 天津做宠物饲料的网站wordpress添加注册页面模板
  • 网站建设公司石家庄php网站开发报价
  • 国外免费网站服务器链接cpa自己做网站