浏览器的一帧/脚本延迟加载方式
什么是一帧
页面一帧一帧 一秒绘制的帧数 细腻 60hz 1s 60帧
干些什么
- 接收输入事件
- 执行事件回调
- 开始一帧
- 执行RAF(Request Animation Frame)
- 布局样式计算
- 页面渲染
- RIC执行(不一定执行)
RIC执行条件 前6步在16.6ms内执行完。执行时间小于30ms。否则要等到执行完才执行下一帧。导致延迟不连续。
RAF是啥
告浏动画 下一帧之前完成
优点: 随系步伐
CPU节能:setTimeout后台会运行,这个不会
函数节流:一次刷新只执一次 多次无用
从输入一个 URL 地址到浏览器完成渲染的整个过程
- 浏览器输入 URL 并回车
- 浏览器查 URL 是否缓存,比较缓存是否过期
- DNS 解析IP
- IP 建立 TCP 连接(三次握手)
- 发送 http 请求
- 服务器处理请求,浏览器接受 HTTP 响应
- 浏览器解析并渲染页面
- 关闭 TCP 连接(四次握手)
http 状态码 204 301 302 304 400 401 403 404 含义
- http 状态码 204 (无内容) 服务器成功处理了请求,但没有返回任何内容
- http 状态码 301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
- http 状态码 302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
- http 状态码 304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
- http 状态码 400 (错误请求) 服务器不理解请求的语法(一般为参数错误)。
- http 状态码 401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
- http 状态码 403 (禁止) 服务器拒绝请求。(一般为客户端的用户权限不够)
- http 状态码 404 (未找到) 服务器找不到请求的网页
脚本延迟加载方式
async: 脚本异步加载,不阻塞页面解析。但!脚本加载完立即执行!若未解析完会被阻塞。
defer: 脚本加载与页面解析同步。页面解析完在执行脚本。不会阻塞页面解析。
动态创建DOM: 监听到文档加载完在创建script脚本
setTimeout: 设置定时器来延迟加载js
js档尾: js脚本放在文档底部
DOM常见的操作
创 createElement createTextNode createAttribute
增 appendChild insertBefore setAttribute
删 removeChild
更 innerHtml innerText textContent
查 querySelector(All) ById className tagname
parentNode childNodes firstChild lastChild previousSibling nextSibling
可视区属性
元素可见 clientWidth(Heigh|Left|Top) content+padding
页面偏移 offsetWidth(Height|left|Top|Parent) content+padding+border+scrollbar
滚动距离 scrollWidth(Height|Left|Top) content+padding+scrollbar(包括滚动条隐藏)
鼠标 clientX(Y)浏 screenX(Y)屏 pageX(Y)档 offsetX(Y)父
如何判断一个元素是否在可视区域中?
上拉加载,下拉刷新?
上拉加载:
document.documentElement.clientHeight + document.documentElement.scrollTop >= document.body.scrollHeight
下拉刷新:
监听 touchStart 起始位 e.touches[0].pageY
监听 touchMove 滑动位置与初始位置差值>0 表示下拉 +c3 translateY特效
监听 touchEnd 若滑到最大 执行callback 设translateY=0 元素回初始位
vue插件:!!!
// 图片懒加载
// <img src="default.png" data-src="https://xxxx/real.png">
function isVisible(el) {
const position = el.getBoundingClientRect()
const windowHeight = document.documentElement.clientHeight
// 顶部边缘可见
const topVisible = position.top > 0 && position.top < windowHeight;
// 底部边缘可见
const bottomVisible = position.bottom < windowHeight && position.bottom > 0;
return topVisible || bottomVisible;
}
function imageLazyLoad() {
const images = document.querySelectorAll('img')
for (let img of images) {
const realSrc = img.dataset.src
if (!realSrc) continue
if (isVisible(img)) {
img.src = realSrc
img.dataset.src = ''
}
}
}
// 测试
window.addEventListener('load', imageLazyLoad)
window.addEventListener('scroll', imageLazyLoad)
// or
window.addEventListener('scroll', throttle(imageLazyLoad, 1000))
Bom对象有哪些
浏览器对象模型
核:window
location: 重加载新url
navigator:浏 属 类
screen:显器信息
history:操历记录 .go(url|3|-1) .forward() .back() .length
内存泄漏有哪几种情况
解释:
动配堆内存未释或无法释
垃回机内存引次0 -> 内回
场景:
全变过多
。未被定或乱引
闭包。未手解闭包内遗内引用
事监未移除
。
定时器
。没clear,导致定时器的回调及其内部依赖的变量都不能被回收
垃圾回收机制:
自内存管理,减负。定找不用变量内存,释
方式:
标记清除:
变->进执境 -> 标 ‘进入环境’(内不能释)
->离境 -> 标‘离开环境’->垃回内清销收
引用计数:
引用表(值引用次),若0,表不用,释
值不再需,引次不为0,拉回无法释,泄
可用=nul解决
Javascript本地存储的方式有哪些 !
cookie:
<4kb
每http请都会发送,若非https+加密 会有险
不设C有效时间,那么,C有效时间等效于会话时间
localstorage:
优:永不过期(除非主删)信同域共享 5M 存过多会卡 受同源策略限
缺:无法设置过期时,只存字符串非对象
setItem, getItem,removeItem, key(0),clear()
sessionStorage:
用法基本localstorage一致,生命周期会话stop,数据删
区:cookie 4k,l和s可5m会更大
时:cookie可设,l不过期除非主动删,s会话结束删
通信方式:cookie自动传到服,可能浪费带宽,服也可写c到client端
l和s在本地,不会自动传到服
场景:
标记或跟踪user行为-->c
适长期存本地->l
敏感一次性登->s
单点登录如何进行实现
多个系中只登1次即可访问all trusted system
SSO独立认证系统
app1,app2,app3,sso
如何实现:
同域单点登录:
步骤: cookie的domain设父域,父域cookie会被子共享 cookie的path设根路径, token存父域 因此所有子都能拿到拿到token了
不同域单点登录
不同域cookie不共享,所以认证中心可专门处理登请
success后token写入->cookie->若无token跳到sso->若有cookie会带到sso验证->未登录跳登录页否则到目标url页->跳前生新token拼在新url后传给系->系拿新token传到认证系统检合法->新token写入cookie->pass
复杂,支持跨域,拓展性好,标准做法
web常见的攻击方式以及如何进行防御
XSS
存储型XSS
攻将恶码提到目标网站SQL-》user open get 服务端恶码执-》取user info 进行operate
反射型XSS
特殊url拼恶码-打开后恶码取出拼在html-解析执行-恶码窃user info-窃数据发到目标网站或冒操作
DOM型XSS
特殊url拼恶码-打开url-恶码执行
区别:
DOM型XSS取恶码与执行恶码都在浏览器执行,为前端js安全漏洞
其他为服务端漏洞
XSS防御
攻击者提交恶意代码-前过滤
如何防浏览器执行恶意代码-尽量不用更改dom的操作-少用innerHTML,outerHTML,document.write
vue少用v-html
CSRF
user-a.com-诱导访问b.com-b.com访问a.com/act=xxx-拿到用户a.com的cookie执行了act=xxx。所以冒充可user执行了a.com的act
无窃取只是冒用
防范:
阻止不明外域访问
增强csrf防范
SQL注入
将恶意的sql查询或输入输入到sql中,服务器解析后会被攻击
防范:
过滤不合法sql字符
对访问库的web应用采用web应用防火墙
Js事件模型有哪些
事件与事件流
- 事件捕获阶段
事件由不太具体的节点最早接受事件, 而最具体的节点(触发节点)
- 处于目标阶段
- 事件冒泡阶段
从下往上由最具体的元素向上到最高层的父
事件模型
- 原始事件模型
- 标准事件模型
- IE事件模型
原始事件模型 | 标准事件模型 | IE事件模型 | |
---|---|---|---|
事件绑定监听函数方式 | 1. HTML代码中直接绑定 2. 通过JS代码绑定 | addEventListener(eventType, handler, useCapture) removeEventListener(eventType, handler, useCapture) | attachEvent(eventType, handler) detachEvent(eventType, handler) |
事件过程 | 1没有传播的概念,没有事件流。事件发生,马上处理。2相同事件的监听函数只能绑定一个,后绑定的会覆盖掉前面的- 如:a.onclick = func1; a.onclick = func2;将只会执行func2中的内容;3无法通过事件的冒泡、委托等机制完成更多事情; | 1先捕获 2到达目标触发目标元素的监听函数 3冒泡 | 1到达目标元素2事件冒泡 |
事件冒泡和捕获
冒泡:事件从最内层向上到document
捕获:事件从最外层开始到最具体的元素
addEventListener(event,function,useCapture)
userCapture: 默认是false冒泡执 设为true为捕获阶段执
阻止冒泡和默认事件
event.stopPropagation()阻止冒泡,不让事件向上document传递
event.preventDefault()
return false 同时阻止冒泡和默认事件
什么是事件代理?哪些应用场景
也称之为事件委托。事件代理的原理是DOM元素的事件冒泡。 事触后,在子和父之间传。传播分成三个阶段
- 捕获阶段:从window对象传到目标节点,捕获阶段不会响应任何事件;
- 目标阶段:在目标节点上触发
- 冒泡阶段:从目标节点传导回window对象。
事件代理即是把一个元素的响应函数委托到另一个元素上。
委托在冒泡阶段完成,将一个或一组元素事件委托在父或最外层,真绑的为最外层元素非目标元素
如ul的li list,每个li绑函耗内存,可绑父级ul上,执行时再匹配。
优点:减内提性能,动绑减重
缺点:focus,blur无冒,无法委托;mousemove,out不断计算,能耗高不适合委;误判,不改绑的绑
e.target 和 e.currentTarget 有什么区别?
当触事时,事从该祖先-目标-祖先 先捕后冒
addEventListener(event,function,useCapture)
userCapture: 默认是false冒泡执 设为true为捕获阶段执
触发的是d,元素为冒泡
e.target(触元素)d
e.currentTarget(绑元素)abcd
浏览器的同源策略
约定,安全策。 域名,协议,端口 两种同源策略: DOM同源:禁不同源页DOM操,iframe XMLHttpRequest同源:禁用XHR向不同服发请
三个标签是允许跨域加载资源:
<img src=XXX> - <link href=XXX> - <script src=XXX>
浏览器为什么要有跨域限制
安全,iframe嵌套一个银行页面,可通过dom拿到password,csrf攻击:user登银行有cookie,访问b后b带cookie请求bank success后泄露data
前端怎么实现跨域请求?
跨域不是请求发不出,能收到结果,只是结果被浏览器拦截了。
解决跨域方案
1. CORS
服务端设置Access-Control-Allow-Origin
字段等。由后端来设置进行可跨域处理
2. Nginx
配置一个代理服务器向服务器请求,再将数据返回给客户端
3.Node中间件代理跨域
在vue.config.js中配置 devServer中设置proxy的target相关info
4.postMessage
HTML5标准中的API
- 多窗之间数据传递
- 页与iframe间数据传递
5. JSONP
动态添加一个script脚本src
如何实现浏览器内多标签页间通信?
localStorage
多个标签共用的存储空间(session是会话级的存储空间,每个标签页都是单独的)
postMessage
两个不同的Iframe间通过window.postMessage()跨源通信 子向父发: window.parent.postMessage(msg, parentUrl) 父接受: window.addEventListener('message', fn(e){e.data}) 安全问题: 接收message,用origin和source验证身份
适配的原理
若页面宽为P = 750px 页分100份,份单位F 设1F的像素值为A(不同设备像素不同) P= 100F*A A=p/100F = 750px/100F = 7.5px/F rem的原理就是份,我们根据稿得到元素份