- 浏览器
- 1.BOM属性有哪些方法?(BOM是浏览器对象模型)DOM(文档对象模型)
- 2.Cookie,sessionStorage,localStorage|本地持久化?
- 3.cookie和session区别(单个cookie保存的数据不超过4K)?
- 4.在地址栏输入一个url到页面渲染完毕,中间发生了什么?=>(网络阶段=>解析阶段=>渲染阶段)
- 6.重绘和重排(回流)?
- 7.跨域|同源策略?
- 8.前端如何反向代理proxy(用来本地测试)?
- 9.浏览器请求头的connection:keep-alive作用?
- 10.多个页面之间通讯问题?
- 12.虚拟dom解决的问题?
- 13.虚拟dom实现原理?
- 14.cookie常用字段?
- 15.http缓存机制了解吗?
- 16.DNS解析过程(DNS是域名系统缩写,DNS解析就是将域名转换成对应的ip地址)?
- 17.a.com的cookie在b.com能访问到吗?
- *18.常见的浏览器内核?
- 19.cookie-session模式和token模式登录有什么不同?
- *20.service worker?
- 21.performance API中哪个指标用来衡量首屏时间?
- 22.load和domContentLoaded事件的先后顺序?
- *23.Data Url是什么?
- 24.gzip如何开启?
- *25.web worker?
- *26.前端大文件存储?
- *27.页面级数据暂存?
- 28.浏览器架构?
- 29.内存泄漏(memory leak)?
- *30.前端性能优化-RAIL了解过吗?
- *31.浏览器有哪些进程了解吗?
- 32.如何统计当前页面出现的所有标签?
- 33.localhost:3000和localhost: 5000的cookie共享吗?
# 浏览器
# 1.BOM属性有哪些方法?(BOM是浏览器对象模型)DOM(文档对象模型)
常用document.getElementById(根据id找到元素) document.getElementsByName(返回指定名称的元素的集合)
# 1.1location对象
location.href返回当前网页的URL
location.search返回URL中参数字符串即?号后的内容
location.hash返回#后面的内容
location.host返回域名 www.baidu.com
location.hostname 返回主域名部分 baidu.com
location.reload() 重载当前页面
2
3
4
5
6
# 1.2history对象
history.go()前进或后退指定的页面数
history.back()后退一页
history.forward()前进一页
2
3
# 1.3navigator对象
navigator.userAgent 返回用户代理头 内容包含浏览器版本手机系统等等
# 2.Cookie,sessionStorage,localStorage|本地持久化?
(localStorage.setItem(key, value) localStorage.getItem(key) sessionStorage设置和取出用法相同) 都是将数据保存在浏览器端 cookie中的数据可以传给服务端 document.cookie="key=value"; 删除只需把过期时间设置为现在以前即可,修改可以用同一个key不同的value来覆盖原来的value。
存储时间:
- cookie在过期时间之前一直有效(cookie不设置过期时间,默认就是关闭浏览器失效)
- sessionStorage仅在当前浏览器窗口关闭前有效
- localStorage可以持久保存数据,需要手动清除 (对于同一个网站,不同标签页共享cookie和localStorage,不共享sessionStorage) 存储大小:
- cookie只有4K
- sessionStorage和localStorage大概可以保存5M信息 服务器交互: cookie会自动在请求头中携带,在服务器和浏览器之间相互传递 sessionStorage和localStorage不会自动把数据发送给服务器
cookie经常用来保存用户登陆状态(http无状态,需要用cookie存用户登陆状态),设置过期时间在浏览器保存用户id session可以用来存储用户的登陆信息
cookie存在跨域问题,现在常用localStorage存token
# sessionStorage多窗口不能共享状态吗?
不一定。 正常来说,每个tab会创建自己的sessionStorage,关闭时会清除对应的sessionStorage 但是在本页面打开新同源页面会临时共享之前页面的sessionStorage(比如通过window.open打开同源的页面) =》等于打开时带过去,但是之后再在原页面修改新页面不会获取到新的值=》MDN上称为复制
# 3.cookie和session区别(单个cookie保存的数据不超过4K)?
- cookie的数据保存在客户端,session的数据保存在服务端
- cookie最大只能保存4K,session的大小没有限制,但是过大会消耗服务器性能
- cookie不安全,攻击者可以通过分析本地的cookie进行cookie欺骗。如果数据考虑到安全需要使用session
# Session工作原理?
浏览器第一次访问服务器时,服务器会创建一个session对象,把产生的session_id放在响应头返回给浏览器, 浏览器收到后会保存到cookie中,下次再访问时,就会把session_id放到请求头发送给服务器, 服务器通过session_id找到对应的session. (用户数据都保存在session中,session机制决定当前客户端只会获取到自己的session)
# cookie
cookie具有不可跨域名性。 设置setMaxAge为0会删除cookie,修改cookie通过新增同名cookie覆盖用来的cookie,只能修改value和maxAge,否则视为新增。 如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。这样浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie
# 4.在地址栏输入一个url到页面渲染完毕,中间发生了什么?=>(网络阶段=>解析阶段=>渲染阶段)
DNS解析->TCP连接->发送http请求->服务器处理请求->返回响应->浏览器渲染页面
# DNS解析过程
先去浏览器找是否有该域名对应的ip地址,没有会去系统缓存中查找 也没有就会去本地域名服务器查找,如果没找到会去根域名服务器请求解析 根域名会返回该域名所属的主域名服务器地址 本地服务器再去主域名服务器查询,主域名服务器没找到会递归向下一级的子域名服务器查找,直到找到返回给本地域名服务器 本地域名服务器将结果进行缓存,并返回给客户机
# TCP连接+HTTP请求
DNS解析得到ip地址和端口后=》 浏览器会构造一个http请求,请求报文包括请求行(method=》get,post等,requestUrl,http version)请求头和请求体 然后把http请求封装在tcp包中,tcp包一次经过(传输层,网络层,数据链路层,物理层)到达服务器
# 浏览器如何渲染页面|浏览器的运行机制
- 解析html文件构建dom树
- 解析css文件构成CSS规则树
- 根据dom树和css规则树构建渲染树
- 布局(layout,计算出每个节点在屏幕的位置)和绘制渲染树(遍历render树,绘制每个节点)
# css是否阻塞html解析,渲染?
css不会阻塞dom树的解析(css解析和dom树的解析是并行操作),但会阻塞dom树的渲染 js会阻塞dom树的解析和渲染 =>如果css不阻塞dom的渲染,那么会在解析css的过程中渲染一次,而css解析完又会重新渲染一次,浪费性能
# 6.重绘和重排(回流)?
(浏览器需要重新渲染树,就是重排(大),只重新绘制受影响的部分是重绘(小))
- 重绘:浏览器重新绘制,改color,background-color等外观属性都会触发
- 重排:隐藏或修改尺寸大小/添加或删除dom元素等都会触发。每个页面第一次加载的时候都会触发一次重排。
- 重排一定触发重绘,重绘不一定触发重排
# 6.1减少重绘重排的方法?
- 少进行dom操作
- 对于多次触发重排的元素可以使用绝对定位脱离文档流
- 统一改变样式,不要一个个元素改
# 7.跨域|同源策略?
同源指的是协议,域名,端口都相同。三者有任一不同,就构成了跨域。同源目的是为了浏览器安全。 后端不存在跨域,跨域是因为浏览器的同源政策。
# 如何解决跨域?
- jsonp(将声明的回调函数名称拼接到请求的url后面,通过在script元素的src属性进行发送。服务器接收到请求后, 把函数名和需要返回给客户端的数据拼接成字符串进行返回,客户端调用之前声明的回调函数对返回的数据进行操作。要求必须是get请求。一定要服务端配合) 浏览器对于script,iframe等标签的src等属性,是没有同源策略限制的
function jsonp ({ url, onData, params }) {
const script = document.createElement('script')
// 一、为了避免全局污染,使用一个随机函数名
const cbFnName = `JSONP_PADDING_${Math.random().toString().slice(2)}`
// 二、默认 callback 函数为 cbFnName
script.src = `${url}?${stringify({ callback: cbFnName, ...params })}`
// 三、使用 onData 作为 cbFnName 回调函数,接收数据
window[cbFnName] = onData;
document.body.appendChild(script)
}
// 发送 JSONP 请求
jsonp({
url: 'http://localhost:10010',
params: { id: 10000 },
onData (data) {
console.log('Data:', data)
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- cors(需要服务器响应头设置允许跨域Access-Control-Allow-Origin: *) =》安全问题 并且不能携带cookie =》cors实际上浏览器发出了请求,服务端也正常返回,只是浏览器不接收。需要设置后才可以接收
- nginx反向代理(正向代理是客户端代理,反向代理是服务端代理)=>反向代理为同一域名就不存在跨域
location /api {
# 或者是 http://localhost:8080
proxy_pass http://api.shanyue.tech; } 常用的是将/api开头的都代理到后端的服务器上 - proxy(本地 webpack-dev-server)
# 8.前端如何反向代理proxy(用来本地测试)?
vue.config.js可以配置会自动代理到后端。相当于vue开启了一个服务器,通过服务器转发你的请求到跨域的后端服务器。(服务器之间没有跨域)
devServer: {
proxy: {
'/api': { // 需要代理的接口
target: '后端url',
changeOrigin: true,//是否跨域
pathRewrite: { // 重定向地址
'^/api': ''
}
}
}
}
2
3
4
5
6
7
8
9
10
11
# 9.浏览器请求头的connection:keep-alive作用?
说明TCP连接保持打开状态,浏览器可以继续发送请求
# 10.多个页面之间通讯问题?
- localstorage存储,监听storage事件,就可以获得存储的值
# 12.虚拟dom解决的问题?
- 用来解决浏览器性能问题。
- 操作dom时,浏览器会从构建dom树开始整个流程执行一遍,频繁操作dom会引起不必要的节点位置计算,影响浏览器性能。
# 13.虚拟dom实现原理?
用js对象模拟dom树,根据diff算法比较新老dom树的差异,再用patch算法将差异应用到真正dom树上
# 虚拟dom和真实dom的区别?
- 虚拟dom是以对象的形式模拟真实dom树
- 操作虚拟dom消耗性能小,并且不会进行重排和重绘的操作
- 操作真实dom,会触发频繁的重绘和重排,性能消耗比较大
- 当HTML解析到script标签时,会暂停构建DOM,直到解析完成才会从暂停的地方重新开始构建
# 14.cookie常用字段?
- path:在该路径下的页面才能访问到cookie
- domain:子域,在该子域下才可以访问cookie,一般设置/=》表示同站点下的所有页面都可以访问这个cookie =》如domain设置为 .a.com,则b.a.com和c.a.com均可使用该Cookie
- name:cookie名称
- value:cookie值
- httponly:设置不允许通过js来访问cookie(dom api的方式,防xss)
- expires:设置过期时间
- *same:限制第三方cookie
# 15.http缓存机制了解吗?
会先判断是否有强缓存,(根据header判断)=》状态码200
如果没有,会发请求到服务器验证是否命中协商缓存,如果也没有,才去服务器直接取数据。
强缓存(Expires或Cache-control,同时存在Cache-control优先级更高,状态码返回200) cache-control: no-cache会缓存,开启后每次会像服务端发请求验证才可以使用缓存 no-store不缓存 强缓存可以通过设置cache-control:max-age或者expires: Sun, 06 Mar 2022 09:28:39 GMT
协商缓存(Last-Modified/If-Modified-Since/If-UnModified-Since,Etag/If-None-Match/If-Match, ETag优先级更高,状态码返回304) 协商缓存可以通过last-modify或者etag来进行判断
Last-Modified/If-Modified-Since 浏览器发送请求,返回的响应头会有last-modify。 当再次请求last-modify会做为If-Modify-Since放到请求头里给服务端校验
Etag/If-None-Match 浏览器发送请求,返回的响应头会有ETag 当再次请求Etag会作为If-None-Match放到请求头里给服务端校验。(服务端校验是否和原来的Etag值相等)
# 强缓存和协商缓存各自存在的问题
- expire可能存在时间不同步的问题,expires用的是绝对时间,cache-control用的是相对时间。
- last-modify有个精度问题,到秒。e-tag没有精度问题,只要文件改变,etag值就发生改变=》etag是服务器随机生成的字符串
# 16.DNS解析过程(DNS是域名系统缩写,DNS解析就是将域名转换成对应的ip地址)?
浏览器缓存->系统缓存->本地域名服务器->根域名服务器->主域名服务器去找->去子服务器去找->继续往下查找直到知道->返回给本地域名服务器->返回给客户机。
- 先检查浏览器缓存是否有域名对应的ip地址
- 没有会去系统缓存中查询
- 都没有采取请求本地域名服务器解析
- 本地服务器没有会去根域名服务器查询
- 根域名服务器返回所查询域的主域名服务器地址
- 本地服务器去主域名服务器查询
- 主域名服务器如果没有找到,会重复向下一级的子域名服务器查询,直到找到
- 本地域名服务器把结果进行缓存,并返回给客户机
- 先去浏览器找是否有该域名对应的ip地址,没有会去系统缓存中查找
- 也没有就会去本地域名服务器查找,如果没找到会去根域名服务器请求解析
- 根域名会返回该域名所属的主域名服务器地址
- 本地服务器再去主域名服务器查询,主域名服务器没找到会递归向下一级的子域名服务器查找,直到找到返回给本地域名服务器
- 本地域名服务器将结果进行缓存,并返回给客户机
拆分就是:客户机(浏览器=>系统) 服务器(本地域名=>根域名=>本地域名 本地域名=>主域名) 递归(主域名的子域名递归查找=》本地域名服务器) 客户机
# 17.a.com的cookie在b.com能访问到吗?
能。在a.com域名下的网站引入b.com域名下的js,这个js需要获取b.com的cookie。SSO单点登录通过统一的验证中心。
# *18.常见的浏览器内核?
- Safari,Chrome都是webkit内核=》chrome现在调整为blink内核
- 浏览器引擎分成:渲染引擎和JS引擎
- 渲染引擎负责将html和css等渲染到页面上,不同内核渲染效果不同,我们平时说的浏览器兼容就是兼容不同内核。
- JS引擎负责解析js来实现网页动态效果
# 19.cookie-session模式和token模式登录有什么不同?
- 因为http协议无状态,所以登录需要辨别客户端的身份。
- cookie-session在负载均衡时有问题,分发的机器可能没有保存用户信息的session。
- token的没有这种问题。
token登陆流程:
- 发送请求到服务端,服务端返回一个带签名的token给客户端
- 客户端存储token,每次请求都携带这个token
- 服务端验证token,成功才返回数据
# *20.service worker?
常用来做缓存文件,提高首屏速度
# 21.performance API中哪个指标用来衡量首屏时间?
window.performance.timing
# 22.load和domContentLoaded事件的先后顺序?
- 初始HTML文档被完全加载和解析后,domContentLoaded事件被触发(无需等待样式,图像的完全加载)
- 当整个页面及所有依赖资源(样式表和图片)都加载完成时,将触发load事件 =》domContentLoad触发,说明dom结构加载完成,而load触发说明页面所有资源都加载完成
# *23.Data Url是什么?
- 平时主要用来把图片转成base64格式嵌入网页,是前缀为data:的URL。
- 缺点:base64格式的图片会比原来的体积大三分之一左右,不会缓存每次都要下载(可以写入到css中,随css被缓存下来)
# 24.gzip如何开启?
通过nginx来开启gzip=》nginx的http配置里加上gzip on|off
# 原理
主要是对重复数据做处理,所以重复度越高的文件可压缩的空间越大
# 可以对图片进行gzip压缩吗
可以,但是基本都不开启,因为可能会使它们变得更大。
# *25.web worker?
- 百万条数据计算,会造成页面假死(GUI渲染线程和JS引擎线程互斥,js有大量计算时,会造成UI阻塞,严重就是页面卡死)
- web worker主要还是通过多线程解决问题。web worker线程中可以执行ajax请求
# *26.前端大文件存储?
可以用indexedDB,按key/value形式存储,更接近于非关系型数据库
# *27.页面级数据暂存?
比如浏览到第几页=》通过把整个组件的data缓存到localStorage来实现。因为$data是只读的,所以要通过Object.assign()把拷贝的对象返回给data
# 28.浏览器架构?
- 浏览器主要由用户界面(包括地址栏,书签等),浏览器引擎(提供了开始加载URL,前进后退等方法),渲染引擎(负责显示请求的内容),网络(HTTP请求),
- 显示后端(包括窗口,组合框等),JS解释器器,XML解析器(将XML文档解析成DOM),存储这八个部分组成。
# 29.内存泄漏(memory leak)?
- 内存泄漏就是指内存得不到释放,最后会导致内存溢出
- 原因:垃圾回收无法回收这块内存(这样这块内存就被浪费了,就是内存泄漏)
# 常见的有=>循环引用及不规范使用闭包导致的内存泄漏(事件重复监听未移除也会导致)
- 闭包导致的内存泄漏无法解决,只能尽量避免使用闭包
- 全局变量
- 定时器
# 优化手段
- 堆内存:参数指针指向null即可
- 堆内存:取消上下文引用即可
# *30.前端性能优化-RAIL了解过吗?
- RAIL是个性能模型,RAIL分别对应Response,Animation,Idle,Load
- Response响应速度
- Animation动画的渲染速度
- Idle最大空闲空间=》可以在空闲空间执行一些延后的任务,但是必须以用户的交互为最高优先级
- Load:页面加载时间
# 分析RAIL工具
- Chrome DevTools
- LightHouse
# *31.浏览器有哪些进程了解吗?
- 浏览器包含了browser进程(浏览器主进程),第三方插件进程,GPU进程(浏览器渲染进程)。
- GPU进程包括:GUI渲染线程,JS引擎线程,事件触发线程,定时器线程,HTTP请求线程。GUI渲染线程和JS引擎线程互斥,一个执行另一个会被挂起
- 浏览器页面初次渲染后,JS引擎线程和事件触发线程工作流程:
- 同步任务在JS引擎线程上执行,形成执行栈
- 主线程外事件触发线程管理一个任务队列,只要异步任务有了结果就在任务队列中放置一个事件
- 执行栈中的同步任务执行完毕,系统就会读取任务队列,如果有异步任务要执行,将其加到主线程的执行栈中并执行其异步任务
# 32.如何统计当前页面出现的所有标签?
# 获取所有标签的API
- document.querySelectorAll('*')
- document.getELementsByTagName('*')
- $$('*')=>浏览器控制台使用
# 实现
// 通过reduce去比较大小,返回最多的标签
const maxBy = (list, keyBy) => list.reduce((x, y) => (keyBy(x) > keyBy(y) ? x : y));
function getFrequentTag() {
// 获取到所有标签
let tags = [...document.querySelectorAll("*")]
.map((x) => x.tagName)
// 通过reduce去计算每个标签出现的次数
tags = tags.reduce((o, tag) => {
o[tag] = o[tag] ? o[tag] + 1 : 1;
return o;
}, {});
return maxBy(Object.entries(tags), (tag) => tag[1]);
}
// 最后返回的是个数组,key是最多的标签,value是出现的次数['LI', 1120]
2
3
4
5
6
7
8
9
10
11
12
13
14
# 33.localhost:3000和localhost: 5000的cookie共享吗?
共享。对浏览器来说,cookie区分域,不区分端口,所以共享。(https和http协议不同也共享)