JS面试八股文(四)
😊JS面试八股文(四)
- 31.精灵图和base64的区别是什么?
- 32.svg格式了解多少?
- 33.了解过JWT吗?
- 34.npm的底层环境是什么?
- 35.HTTP协议规定的协议头和请求头有什么?
- 36.说一下浏览器的缓存策略
- 37.说一下什么是“同源策略”?
- 38.防抖和节流是什么?
- 39.解释一下什么是JSON?
- 40.当数据没有请求过来的时候,该怎么做?
- 41.有没有做过无感登录?
- 42.大文件上传是怎么做的?
😊各位小伙伴们,本专栏新文章出炉了!!!
31.精灵图和base64的区别是什么?
精灵图和Base64编码都是用于优化Web页面图像加载的技术。
精灵图是一种将多个小图标或图像合并到一张大图中的技术。通过这种方式,可以减少http请求的次数,从而提高页面加载速度。
缺点:
- 尺寸限制:如果图像数量过多,精灵图的尺寸会变得很大,增加了单个文件的大小。
- 布局调整困难:如果需要调整图像的位置或大小,需要重新制作精灵图,较为麻烦。
- 不适应动态内容:对于动态生成的图像,使用精灵图较为不方便。
Base64编码是一种将二进制数据转换为ASCII字符串的方法。在Web开发中,常用于将图像等小文件嵌入到CSS或HTML文件中,从而减少HTTP的请求次数。
缺点:
- 增加文件大小:Base64 编码后的数据量会增加约
33%
,这可能会导致CSS或HTML文件体积增大。 - 不利于缓存:嵌入的图片无法单独缓存,每次请求页面都需要重新加载。
- 不适用于大文件:对于较大尺寸的图像,Base64 编码后的数据量较大,可能会影响页面加载速度。
32.svg格式了解多少?
SVG是一种基于XML的矢量图像格式,SVG用于描述二维图形,支持动画和互操作性。
SVG是一种非常适合用于Web页面的矢量图形格式,它具有可缩放性、小文件大小,动画和交互性等优点。SVG适用于图标、地图、图表等多种应用场景。
33.了解过JWT吗?
JWT(JSON Web Token
)是用于在各方之间以安全的方式传输信息的紧凑且安全的机制。通常用于Web认证。JWT由三部分组成:头部(Header)、载荷、以及签名。
- 头部(Header)包含了关于JWT的基本信息,比如其类型和使用的签名算法。
- 载荷是实际存储数据的部分,也被称为声明,包含用户的ID,用户名等信息。
- 签名是用来确保客户端和服务器的传输过程中令牌没有被改变的部分,接收方会使用密钥来验证签名。
JWT的主要优点是自包含,所有需要的信息都包含在令牌中,不需要查询数据库或者其他服务来验证用户身份或访问权限,因此,可以轻松地通过URL、POST参数或在HTTP header中作为Bearer Token发送。
JWT的认证流程
- 用户登录请求:用户通过用户名和密码向服务器发起登录请求。
- 用户身份验证:服务器验证用户的凭证(一般是用户名和密码)。
- 发放JWT:如果用户身份验证成功,服务器会创建一个
JWT
,并将该令牌发送回客户端,这个令牌包含了用户的身份信息和其他必要信息,如权限范围等。 - 客户端存储JWT:客户端收到
JWT
后,会将其存储在浏览器的LocalStorage
、SessionStorage
或者是Cookie
中,以便后续请求时使用。 - 请求携带JWT:当客户端需要访问受保护的资源时,会在每个HTTP请求的
Authorization
头中附加JWT,格式通常是Bearer<token>
。 - 服务器验证JWT:服务器收到带有JWT的请求后,会验证JWT的签名,检查其有效性(如是否已过期,是否被篡改等),并从中解析出用户的身份信息和权限等。
- 授权访问:如果JWT验证无误,服务器允许客户端访问请求的资源,否则,拒绝访问,并返回相应的错误信息。
34.npm的底层环境是什么?
npm(Node Package Manager
)是一个用于管理和安装Node.js应用程序依赖项的工具。
npm的底层环境主要基于以下几个关键组件和技术:
- Node.js:npm是为Node.js设计的,所以他的运行环境首先是Node.js运行时本身。
- JavaScript:npm的核心功能和大多数包都是用JavaScript编写的。
- npm CLI:负责解析命令行输入,执行包管理操作,如安装、卸载、更新模块等。
- 等等…
npm的底层环境是构建在Node.js
和JavaScript
之上的,它依赖于Node.js
提供的运行时环境和API来执行其功能。
35.HTTP协议规定的协议头和请求头有什么?
协议头(Protocol Line)
对于HTTP
请求,协议头并不是真正的“头”,而是请求行(reque-line
),它包括以下三个部分:
- 方法(
Method
):指定了请求的方法,如GET、POST、PUT、DELETE等。 - 请求URL(
Request-URL
):表示请求的资源标识符。 - HTTP版本(
HTTP-Version
):指定所使用的HTTP协议版本,如HTTP/1.1或HTTP/1.2。
对于HTTP相应,协议头被称为状态行(status-line
),它包含以下三个部分:
- HTTP版本(
HTTP-Version
):响应的HTTP协议版本。 - 状态码(
Status Code
):一个三位数字代码,表示请求的结果。 - 状态消息(
Reason Phrase
):一个可选的状态描述,通常是一个文本消息
请求头(Request Headers)
请求头包含了许多客户端向服务器传递的元数据。一些常见的请求头字段包括:
Accept
:报名客户端接受那些类型的数据。Accept-Language
:告诉服务器客户端首选的语言。Accept-Encoding
:指明客户端支持的内容编码方式。如gzip
。Authorization
:用于发送认证信息。Content-Type
:指明发送到服务器的实体主体的数据类型。Cookie
:用于携带客户端的Cookie信息。User-Agent
:描述了发出请求的客户端软件的名称和版本。If-Modified-Since
:询问服务器自从某个日期之后是否有修改。
响应头(Response Header)
响应头则是服务器向客户端传递的元数据,常见的响应头字段包括:
Content-Type
:描述了返回的内容的数据类型。Content-Length
:返回的内容长度。Set-Cookie
:用于设置客户端的Cookie。Location
:用于重定向接收者到一个新的位置。Cache-Control
:指定缓存相关指令。Expires
:指明了响应何时开始被认为是陈旧的。server
:服务器的名称或版本。
36.说一下浏览器的缓存策略
浏览器的缓存策略是为了减少加载时间,节省带宽以及提高用户体验而设计的一系列规则。缓存策略主要涉及两种缓存类型:强制缓存(Mandatory Caching
)和验证缓存(Validating Caching
)。
强制缓存
强制缓存是通过HTTP响应头中的Cache-Control
和Expires
来控制的。当浏览器接收到这些指示时,他会直接使用缓存副本而不向服务器发送请求。
当Cache-Control
中的max-age
未过期或者当前时间早于Expires
指定的日期时,浏览器直接使用缓存内容。
验证缓存
验证缓存是指当强制缓存不在有效时,浏览器会发送一个条件请求到服务器来验证缓存副本是否仍然有效。
- Last-Modified/If-Modified-Since:当响应中包含
Last-Modified
日期时,浏览器可以在后续请求中使用If-Modified-Since
头来询问服务器资源是否已经发生改变。 - Etag/If-None-Match:Etag是一个唯一的标识符,代表资源的一个特定版本。服务器可以返回一个Etag给浏览器,然后浏览器可以在后续的请求中使用
If-None-Match
头来验证资源是否发生了变化。
如果服务器确认资源未被修改,则返回一个304
状态码而不是整个资源,然后浏览器就可以继续使用现有的缓存副本。
浏览器缓存层次
除了上述两种缓存策略外,浏览器还可以根据不同的场景使用不同层次的缓存:
- 内存缓存(
Memory Cache
):这是最短暂的缓存形式,仅在页面加载期间有效。 - HTTP缓存(
HTTP Cache
):上述说的就是HTTP缓存,它依赖于HTTP响应头来决定缓存策略。 - Service Worker Cache API:这种缓存机制允许开发者在客户端存储响应,并在离线情况下提供服务。
37.说一下什么是“同源策略”?
同源策略是Web安全的一个重要概念,用于限制一个Web页面上的脚本与其他来源的数据之间的交互。这个策略的主要目的是为了防止恶意脚本访问或修改敏感数据,从而保护用户的隐私和数据安全。
同源策略的定义
同源策略规定,一个Web应用中的脚本只能读写和操作相同来源的文档和资源。只有当其他数据来源的协议、域名以及端口号与此Web应用相同,请求才不会被拦截。
实现跨域的常见方式
- JSONP(JSON with Padding):是一种早期的跨域解决方案,主要用于GET请求。
- CORS(Cross-Origin Resource Sharing):CORS是一种更为现代且灵活的跨域解决方案,它允许服务器通过设置响应头来明确指出哪些源可以访问其资源。
- 使用代理服务器:客户端向代理服务器发送请求,代理服务器再向目标服务器发送请求,并将结果返回给客户端。
- WebSocket:WebSocket是一种全双工的通信协议,他可以在客户端和服务器之间建立持久连接,虽然WebSocket本身不是针对跨域问题的解决方案,但他可以绕过同源策略的限制。
38.防抖和节流是什么?
防抖(Debounce)和节流(Throttle)是两种常见的函数优化技术,主要用于避免短时间内频繁触发事件导致的性能问题。这两种技术可以有效地控制函数的调用频率,从而提高应用的性能和响应性。
防抖
防抖技术用于防止在一系列连续的事件发生时重复调用一个函数。其基本思想是在一系列事件结束后的一段时间内如果没有新的事件发生,才执行一次函数。如果在这段时间内又有新的事件触发,则重新计算这段时间。
实现方式
防抖函数常使用SetTimeout
来实现,当一个事件触发时,会设置一个定时器,如果在这个定时器超时之前没有新的事件触发,则执行函数,如果有新的事件触发,则清除前一个定时器并设置一个新的定时器。
<body><input type="text" id="search-input" placeholder="请输入搜索内容"/><script>//防抖函数的定义function debounce(func, wait) {//定时器的IDlet timeoutId;return function () {const context = this;const args = arguments;//清除上一个定时器clearTimeout(timeoutId);timeoutId = setTimeout(function () {func.apply(context, args);}, wait);};}//搜索函数function search(term){console.log("搜索的内容为:",term);}// 使用防抖const debouncedSearch = debounce(search,500);document.addEventListener('DOMContentLoaded',function(){const input = document.getElementById("search-input");input.addEventListener('input',function(event){debouncedSearch(event.target.value);})})</script>
</body>
防抖函数(debounce
):这个函数的目的是限制某个操作在一定时间内只能执行一次,在上述例子中用于控制搜索操作的频率,防止用户快速输入时频繁触发搜索。此函数接受两个参数,第一个参数func
为要防抖的函数,第二个参数wait
为等待的时间(毫秒)。timeoutId
用于存储定时器的ID,以便在输入时清除之前的定时器。func.apply(context, args);
在这一句中,context
是当前事件的上下文(通常是input
元素),args
就是下面使用函数传入的event.taget.value
。在500
毫秒后执行传入的Search
函数,并传入当前的context
和args
。
搜索函数(search
):这个函数接受一个参数term
(用户输入的搜索内容),并在控制台打印出该内容。
添加事件监听
将debounce
函数应用于search
函数,常见一个新的函数debounceSearch
,这个函数在用户停止输入的500
毫秒后将调用Search
函数。
document.addEventListener('DOMContentLoaded',function(){})
这个事件确保在整个DOM树构建完成之后在执行代码。
input.addEventListener('input',function(event){}
这个事件监听器用于监听用户在输入框输入内容的变化。当用户输入时,会调用debounceSearch
函数,并将当前输入框的值作为参数传递。
使用场景
- 输入框输入时触发的搜索建议,避免每次按键都发送请求。
- 窗口大小变化时调整布局。
- 其他需要对事件进行“冷静期”处理的情况。
节流
节流技术用于控制函数的执行频率,确保在一个固定的时间间隔内函数最多只被执行一次。不同于防抖的是,节流并不关心事件流的结束,而是关注事情发生的频率。
实现方式
节流可以通过固定时间间隔执行函数,也可以通过上一次执行时间和当前时间的差值来判断是否执行函数。
<div style="height: 2000px; background-color: aqua;"></div>
<script>// 节流函数的定义function thorttle(func,wait){let previous = 0;return function(){const context = this;const args = arguments;const now = Date.now();if(now - previous > wait){func.apply(context,args);previous = now;}}}// 滚动处理函数function onScroll(){console.log("滚动的位置:",window.scrollY);}// 使用节流const throttleOnScroll = thorttle(onScroll,500);document.addEventListener("DOMContentLoaded",function(){window.addEventListener("scroll",throttleOnScroll);})
</script>
节流函数(throttle(func,wait)
):接收两个参数,func
参数为要执行节流的函数(也就是代码中的onScroll
),wait
表示节流的时间间隔(毫秒为单位)。在节流函数中previous
记录上一次调用func
的时间戳,初始值为0。
这个函数会在每次触发时执行,首先获取当前的上下文context
和传入的参数args
。然后获取当前的时间戳,如果当前时间与上次调用时间的差值大于设定的wait
,就调用func
并将previous
设置为当前时间,保证func
在wait
时间内只会被调用一次。
滚动处理函数(onScroll
):当用户滚动页面时,会打印出当前的滚动位置(Window.scrollY
),表示垂直方向的滚动距离。
使用节流
使用throttle
函数包装onscroll
函数,并设定wait
的值,返回新的函数throttleOnScroll
,在用户滚动时使用。
事件监听
对window
对象进行监听,监听事件为scroll
,处理事件为throttleOnScroll
函数。
使用场景
- 鼠标滚轮滚动,鼠标移动等高频事件。
- 页面滚动时的监听事件。
- 其他需要限制函数调用频率的情况。
防抖确保在一段时间内函数只被执行一次,而节流则确保函数在一定时间内不会被过度执行。
39.解释一下什么是JSON?
JSON
是一种轻量级的数据交换格式,是完全独立于编程语言的文本格式。其数据格式由键值对组成。JSON广泛用于Web开发中,特别是在客户端和服务器之间的数据交换。
使用场景:
- API数据交换
- 配置文件:例如Vue的
package.json
- 数据存储:例如
NoSQL
数据库中 - 消息传递:在分布式系统中,JSON可以用来在节点之间传递消息。
JavaScript提供了内置的函数JSON.parse()
和JSON.stringify()
来方便地转换JSON数据。
JSON.parse(jsonString)
:解析一个JSON格式的字符串,并返回一个JavaScript对象。JSON.stringify(value)
:讲一个JavaScript值(通常是对象或数组)转换为JSON字符串。
40.当数据没有请求过来的时候,该怎么做?
- 检查请求是否正确发送。
- 检查服务器状态
- 添加错误处理和重试机制。
- 添加用户提示
41.有没有做过无感登录?
无感登录时一种用户体验优化技术,目的是让用户在无需重新输入用户名和密码的情况下,无缝地继续会话。
实现无感登录的几种常用方法:
- 使用Token机制
目前最常用的一种实现方式。用户在首次登录时,服务器会返回一个访问令牌(Access Token)和一个刷新令牌(Refresh Token),Access Token
用于访问受保护的资源,而Refresh Token
用于在Access Token
过期时请求新的Access Token
。
- 使用Cookie存储Session ID
这种方法适用于服务端会话管理。用户登录后,服务器会在响应中设置一个包含Session ID的Cookie,客户端在每次请求时都会自动带上这个Cookie。
- 使用LocalStorage或者SessionStorage存储Token
这种方式适用于单页面应用(SPA)或者其他需要长时间保持登录状态的应用,将Access Token
存储在客户端的LocalStorage
或者SessionStorage
中,并且在每次请求时自动添加到请求头中。
- 使用WebSocket保持连接
对于需要实时通信的应用,可以使用WebSocket保持与服务器的长连接,这样可以在用户活动时实时检测用户状态,并在必要时自动续签会话。
42.大文件上传是怎么做的?
大文件上传可能会导致网络拥塞、服务器压力大等问题。
- 分块上传
原理:
将大文件分割成多个小块,分别上传到服务器。每个块上传完成之后,服务器进行校验并存储。所有块上传完毕之后,服务器将这些块合并成完整的文件。
实现步骤:
- 客户端分块:将文件分成若干个块。
- 上传每个块:逐个上传每个块,并记录已上传的块。
- 服务器校验:服务器收到每个块后进行校验(如MD5哈希校验),确保数据完整性。
- 合并块:所有块上传完毕后,服务器会将这些块合并成完整的文件。
- 断点上传
原理:
如果上传过程中出现网络中断或其他问题,可以从断点处继续上传,而不是重新上传整个文件或某个块。
实现步骤:
- 记录上传进度:客户端记录每个块的上传进度。
- 检查已上传的块:上传前检查那些块已经成功上传,就跳过这些块。
- 继续上传剩余块:上传未上传的块,并确保块顺序正确。
- 使用第三方存储服务(如云存储)
- 使用Web Workers
🎨觉得不错的话记得点赞收藏呀!!🎨
😀别忘了给我关注~~😀