浏览器面试题
浏览器面试题
- 1.常见的浏览器内核有哪些?
- 2.浏览器的主要组成部分有哪些?
- 3.说一说从输入URL到页面呈现发生了什么?
- 4.浏览器重绘域重排的区别?
- 5.CSS加载会阻塞DOM吗?
- 6.JS会阻塞页面吗?
- 7.说一说浏览器的缓存机制?
- 8.Cookie相关与HttpOnly
- 9.说说跨站请求伪造(CSRF)攻击
- 10.浏览器的存储
- 11.HTTP与HTTPS、第三方证书工作原理、以及HTTP各个版本
- 12.怎么传递引用类型而互不影响 ?(深拷贝)
- 13.静态多态
- 14.怎么用js实现类的修饰符 private public
- 15.前端如何性能优化
1.常见的浏览器内核有哪些?
浏览器的内核分成两部分:
渲染引擎
和JS引擎
(⚠️注意:我们常说的浏览器内核就是指JS引擎)
FireFox 和 Chrome 使用不同的渲染引擎和 JavaScript 引擎:
-
FireFox:
- 渲染引擎: Gecko
- JavaScript 引擎: SpiderMonkey
-
Chrome (以及大多数基于Chromium的浏览器,如新的Microsoft Edge):
- 渲染引擎: Blink (注意:Blink是从WebKit分叉出来的,WebKit是早期Chrome和现在的Safari使用的渲染引擎)
- JavaScript 引擎: V8
2.浏览器的主要组成部分有哪些?
浏览器是一个复杂的应用程序,其主要组件如下:
-
用户界面 (User Interface): 这部分包括地址栏、书签栏、前进/后退按钮、刷新按钮等。简而言之,除了您在浏览页面时看到的内容外,用户界面包括了其他所有部分。
-
浏览器引擎 (Browser Engine): 该模块在用户界面和渲染引擎之间起到中介的作用,传递命令。
-
渲染引擎 (Rendering Engine): 负责显示请求的内容。如果请求的是HTML内容,渲染引擎就负责解析HTML和CSS,并将解析后的内容显示在屏幕上。
-
网络 (Networking): 用于网络调用,例如HTTP请求。它负责发送查询和下载网页、图片、其他资源。
-
JavaScript解释器 (JavaScript Engine): 解析和执行JavaScript来实现网页的动态功能。
-
数据存储 (Data Storage): 这是持久层。浏览器需要在本地存储各种数据,如cookies。HTML5引入了web storage,允许网页本地存储数据。
交互流程:
-
当您在地址栏中输入URL并按下Enter时,用户界面指示浏览器引擎加载请求的网页。
-
浏览器引擎告知网络模块获取该URL的内容。
-
一旦网络模块完成下载网页的主要内容(通常是HTML文件),它将数据传递给渲染引擎。
-
渲染引擎开始解析HTML,并在解析过程中遇到其他资源(如CSS文件、JavaScript文件或图片)时请求网络模块加载它们。
-
如果渲染引擎在解析HTML时遇到JavaScript,并且JavaScript没有被延迟或异步加载(deffer\async异步加载js),则渲染引擎暂停HTML解析并将控制权交给JavaScript引擎。一旦JavaScript引擎完成执行,控制权返回渲染引擎。
-
渲染引擎根据HTML和CSS创建渲染树,并在屏幕上显示内容。
-
JavaScript可以用来修改渲染后的页面,它通过DOM(文档对象模型)与页面内容交互。
-
用户与页面交互(例如点击按钮)可能会触发JavaScript代码的执行,这可能会导致页面内容的更改,进而可能会导致重新渲染部分或全部页面。
-
浏览器的数据存储模块在整个过程中也会起到作用,例如,当页面设置或查询cookie时。
⚠️注意:与大多数浏览器不同的是,谷歌(Chrome)浏览器的每个标签页都分别对应一个渲染引擎实例。每个标签页都是一个独立的进程(进程和线程)
3.说一说从输入URL到页面呈现发生了什么?
这个题可以说是面试最常见也是一道可以无限难的题了,一般面试官出这道题就是为了考察你的前端知识深度。
-
URL解析:浏览器首先会解析输入的URL,提取出协议**(如HTTP、HTTPS)**、域名(如www.example.com)和路径等信息。
-
DNS解析:浏览器会向本地DNS解析器发送一个DNS查询请求,以获取输入域名对应的IP地址。如果本地DNS缓存中存在域名的解析结果,则直接返回IP地址;否则,本地DNS解析器会向根DNS服务器、顶级域名服务器和授权域名服务器等级联查询,最终获取到域名的IP地址。
-
建立TCP连接:浏览器使用获取到的IP地址,通过TCP/IP协议与服务器建立网络连接。这个过程通常经历三次握手,确保客户端和服务器之间的可靠连接。
-
发起HTTP请求:一旦建立了TCP连接,浏览器就会发送一个HTTP请求到服务器。请求中包含了请求行(请求方法,如GET或POST,以及请求的资源路径)、请求头(如Accept、User-Agent等)和请求体(对于POST请求)等信息。
-
服务器处理请求:服务器接收到浏览器发送的HTTP请求后,会根据请求的路径和参数等信息,处理请求并生成相应的响应。
-
接收响应:浏览器接收到服务器发送的HTTP响应后,会解析响应头和响应体。响应头包含了状态码(如200表示成功,404表示资源未找到)和其他元信息,响应体包含了服务器返回的实际内容(如HTML、CSS、JavaScript、图片等)。
-
渲染页面:浏览器开始解析响应体中的HTML文档,并构建DOM(文档对象模型)树。同时,它还会解析CSS文件和JavaScript代码,并进行样式计算、布局和渲染。最终,将解析后的内容显示在用户界面上,呈现出完整的页面。
-
关闭TCP连接(四次挥手):一旦页面呈现完成,浏览器会关闭与服务器之间的TCP连接。如果页面中存在其他资源(如图片、脚本、样式表),则会继续发送相应的HTTP请求来获取这些资源,并重复执行步骤5到步骤7,直至所有资源加载完成。
4.浏览器重绘域重排的区别?
- 重排: 布局改变,重排成本高
- 重绘: 样式改变,布局没变
重绘不一定导致重排,但重排一定绘导致重绘
如何触发重绘和重排?
任何改变 用来构建渲染树的信息 都会导致一次重排或重绘:
- 添加、删除、更新DOM节点
- 通过display: none隐藏一个DOM节点-触发重排和重绘
- 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化
如何避免重绘或重排?
- 集中改变样式:比如使用class的方式来集中改变样式
- 使用document.createDocumentFragment():我们可以通过createDocumentFragment创建一个游离于DOM树之外的节点,然后在此节点上批量操作,最后插入DOM树中,因此只触发一次重排
- 提升为合成层
使用 CSS 的 will-change 属性将元素提升为合成层。有以下优点:交由 GPU 合成,比 CPU 处理要快 - 使用 CSS3 的 transform 和 opacity 属性来进行动画效果,它们可以利用 GPU 加速,减少重排的发生。
5.CSS加载会阻塞DOM吗?
先上结论:
- CSS不会阻塞DOM的解析,但会阻塞DOM的渲染
- CSS会阻塞JS执行,但不会阻塞JS文件的下载
为什么CSS不会阻塞DOM的解析,但会阻塞DOM的渲染?(DOM和CSSOM通常是并行构建的,所以CSS加载不会阻塞DOM的解析,前一个DOM的解析指的是HTML的解析构建DOM树,后一个DOM的渲染指的是DOM与CSSOM结合的渲染树的渲染)
CSS解析之前,由HTML解析出来的DOM已经开始构建?(并行的,但是,如果dom解析到一半,遇到js改变css样式则需要等待css被加载完毕,这也是为什么css会阻塞JS的执行)
-
DOM 构建: 当浏览器开始接收到HTML内容时,它会开始构建DOM(Document Object Model)。DOM是一个树形结构,表示页面的内容结构。DOM的构建是逐步的,也就是说,当浏览器接收到HTML内容的一部分时,它就开始构建DOM的这一部分。
-
CSSOM 构建: 同时,当浏览器遇到外部CSS文件(通过
<link>
标签)或内部样式(通过<style>
标签)时,它开始构建另一个树结构,称为CSSOM(CSS Object Model)。CSSOM表示样式规则及其如何应用到DOM上。 -
渲染树 构建: 一旦浏览器有了DOM和CSSOM,它会结合这两者来创建渲染树。渲染树只包含在页面上可见的元素以及这些元素的样式。
-
布局: 当渲染树被创建并完成之后,浏览器开始了布局过程,也被称为"reflow"。这是计算每个可见元素的大小和位置的过程。
-
绘制: 经过布局之后,浏览器会开始绘制页面,将每个元素渲染到屏幕上。
但是,一个重要的点要注意:当浏览器在构建DOM时遇到<script>
标签,并且该脚本不是async
或defer
的,浏览器会暂停DOM的构建,直到脚本执行完毕。如果此时的JavaScript试图访问某些尚未解析的CSS属性,那么浏览器可能需要先完成CSSOM的构建。这就是为什么阻塞的(非异步的)JavaScript和大量的CSS可能会导致页面加载延迟的原因之一。
6.JS会阻塞页面吗?
先上结论
JS会阻塞DOM的解析,也会与渲染线程互斥,因此也就会阻塞页面的加载
这也是为什么要把JS文件放在最下面的原因
由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即 JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。
因此为了防止渲染出现不可预期的结果,浏览器设置 「GUI 渲染线程与 JavaScript 引擎为互斥」的关系。
当浏览器在执行 JavaScript 程序的时候,GUI 渲染线程会被保存在一个队列中,直到 JS 程序执行完成,才会接着执行。
因此如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
7.说一说浏览器的缓存机制?
认识浏览器缓存:
当浏览器请求一个网站时,会加载各种资源,对于一些不经常变动的资源,浏览器会将他们保存在本地内存中,下次访问时直接加载这些资源,提高访问速度。
浏览器缓存分类:
- 强缓存:不会发请求给服务器,直接从本地缓存读取,返回状态码是200(from cache)。
- 协商缓存:会发请求给服务器,比对资源是否有变化,如果没有变化,返回状态码是304(not modified),然后从本地缓存读取。
什么样的资源使用强缓存,什么样的资源使用协商缓存?
-
使用强缓存的资源:不经常变化的资源(例如 CSS、JavaScript 文件,图片、视频等)
-
使用协商缓存的资源:经常变化的资源(例如来自数据库的内容、新闻、博客帖子等,它们可能经常变化)
如何实现强缓存?
设置Expires与Cache-Control,Expires逐渐被Cache-Control取代。
- Cache-Control:控制缓存字段,后端配置,常见的取值包括:
- public:表示资源可以被任何缓存(包括浏览器和CDN)缓存。
- private:表示资源只能被单个用户的私有缓存缓存,不能被共享缓存(如CDN)缓存。
- no-cache:强制使用协商缓存,即每次请求都要与服务器确认资源是否有更新。
- no-store:不使用缓存,每次重发请求,包括请求响应体。
- max-age=<seconds:用来设置强缓存,表示资源的有效期,即从请求时间开始,缓存会在指定的秒数内有效。
- s-maxage=<seconds:类似于 max-age,但仅适用于共享缓存(如CDN)。
- Expires:这是一个过时的字段,被 Cache-Control 所取代。它指定了一个绝对的过期日期,由于客户端与服务器端的时间不同,可能存在不准确的问题。
如何实现协商缓存?
- Cache-Control中的no-cache
- Last-Modified / If-Modified-Since
- ETag(哈希值) / If-None-Match
后面两种方法通常与Cache-Control
指令一起使用。
与缓存相关的配置方法:
请求头(Request Headers):
If-None-Match
: 等于上次服务器响应体中的ETag值,询问服务器资源是否被修改。If-Modified-Since
: 询问资源是否过期。
响应头(Response Headers):
-
Cache-Control
: 指明了资源如何被缓存的指令,例如max-age
,no-cache
,private
,public
等。 -
Expires
: 设置资源过期的绝对时间。 -
ETag
: 服务器为资源生成的一个标识符。 -
Last-Modified
: 表示资源最后一次被修改的时间。 -
Vary
: 告诉缓存机制哪些请求头部信息应该被考虑进去。
缓存完整流程图:
8.Cookie相关与HttpOnly
- 什么是
HttpOnly
?为什么我们需要它?
HttpOnly
是一个用于设置 HTTP Cookie 的属性,它的作用是限制客户端(通常是浏览器)对 Cookie 的访问,只允许通过 HTTP 或 HTTPS 协议进行访问,而禁止通过脚本(如 JavaScript)进行访问。
使用 HttpOnly
属性可以提高 Web 应用程序的安全性:防止跨站脚本攻击(XSS):浏览器将禁止 JavaScript 访问带有该属性的 Cookie
- 除了
HttpOnly
,哪些其他标志或属性可以提高Cookie的安全性?
-
Secure
属性:只允许通过 HTTPS 连接传输 Cookie。 -
SameSite
属性:SameSite
属性用于定义 Cookie 发送的规则,以防止跨站点请求伪造(CSRF)攻击。可以将SameSite
属性设置为以下值之一:Strict
、Lax
或None
。Strict
模式完全禁止跨站点发送 Cookie,Lax
模式在导航到目标站点之前仅允许在安全上下文(指顶导)中发送 Cookie,而None
模式允许在任何情况下发送 Cookie(需要同时设置Secure
属性)。使用适当的SameSite
设置可以限制 Cookie 的发送范围,减少 CSRF 攻击的风险。 -
Domain
属性:通过设置Domain
属性,可以限制 Cookie 的作用域。将Domain
属性设置为与当前网站的主域名匹配,可以防止恶意网站访问到另一个网站的 Cookie。这可以提高 Cookie 的隔离性和安全性。 -
Path
属性:Path
属性用于限制 Cookie 的可见性。将Path
属性设置为特定的路径,可以确保 Cookie 只在与该路径匹配的 URL 下发送。这样可以防止其他路径下的恶意脚本访问和窃取 Cookie。 -
定期更新和轮换 Cookie:定期更改敏感 Cookie 的值,增加攻击者窃取 Cookie 的难度。同时,使用有限的有效期限制 Cookie 的生命周期。
-
CSP(内容安全策略):通过 CSP,可以定义网页可以加载的资源源,限制恶意脚本的执行和 Cookie 的访问。
res.cookie('cookieName', 'cookieValue', { httpOnly: true,secure: true,sameSite: 'Strict',domain: 'example.com',path: '/'
});
SameSite
场景:
那我如果设置SameSite中的Strict,那是不是完全禁止跨站点发送 Cookie。也就是在evil.com里面点。也不会携带cookie了?
您完全正确。SameSite
属性是一个相对较新的 Cookie 属性,用于增强浏览器中的跨站点请求的安全性。该属性有三个可能的值:Strict
、Lax
和 None
。
-
当设置为
SameSite=Strict
时,该 Cookie 仅在请求来自同一站点时发送。这意味着,即使用户已经在bank.com
上登录,如果他们访问了evil.com
并从那里尝试通过<img>
标签或任何其他方式触发一个跨站点请求,浏览器将不会附带与bank.com
相关的任何SameSite=Strict
的 Cookie。 -
SameSite=Lax
是一个稍微宽松一点的版本,它允许一些安全的跨站点请求(例如GET请求)携带 Cookie,但不允许跨站点的 POST 请求携带 Cookie。这可以避免许多 CSRF 攻击,同时仍然允许某些跨站点的使用场景。 -
SameSite=None
意味着 Cookie 可以在任何跨站点请求中发送,但这需要与Secure
标志一起使用,这意味着 Cookie 只能通过 HTTPS 发送。
为了增强安全性,许多现代浏览器已经开始更改其对 SameSite
的默认行为,将其默认设置为 Lax
。这就是为什么在某些场景中,如果没有明确设置 SameSite
属性,您可能会看到一些关于 Cookie 行为的变化。
综上所述,设置 SameSite=Strict
确实可以大大减少 CSRF 攻击的风险,因为它会完全阻止跨站点发送 Cookie。
如何理解Samesite = Lax?:
- 假设用户已登录
bank.com
并获取了一个带有SameSite=Lax
属性的cookie。 - 用户访问一个第三方的恶意网站
evil.com
。 - 在
evil.com
上有一个尝试利用CSRF漏洞发起的XHR请求,目标是bank.com/transferMoney
。由于cookie设置为Lax
,这个跨站XHR请求不会携带bank.com
的cookie,从而防止了潜在的CSRF攻击。 - 但是,如果用户在
evil.com
上点击一个指向bank.com
的链接,由于这是一个顶层导航请求,bank.com
的cookie将会被发送,尽管是从evil.com
触发的。
总结:从而确保不破坏用户的正常浏览体验.
SameSite与Secure的不同:
SameSite
属性用来控制 Cookie 是否能够在跨站请求中被发送。Secure
属性确保 Cookie 只能通过 HTTPS 协议发送。
如何理解Domain属性?:
Domain
属性在Cookie中定义了哪些域名可以访问该Cookie。它有助于定义Cookie的范围。
默认情况下,Cookie只能被创建它的页面所访问。但是,如果你设置了Domain
属性,这个Cookie就可以被此域下的其他子域所访问。
假设你有一个主域example.com
,以及两个子域sub1.example.com
和sub2.example.com
。
-
如果你在
sub1.example.com
上设置了一个Cookie,并未指定Domain
属性,那么默认情况下,只有sub1.example.com
可以访问该Cookie,sub2.example.com
和example.com
都无法访问。 -
但如果你在
sub1.example.com
设置了一个Cookie,并且指定了Domain
属性为.example.com
(注意域名前面的点,表示这是一个通配符匹配),那么example.com
、sub1.example.com
、sub2.example.com
都可以访问该Cookie。
需要注意的是,为了安全性,你不能设置一个与当前域完全不相关的Domain属性。也就是说,sub1.example.com
不能设置一个Domain
为.anotherexample.com
的Cookie。
另外,使用Domain
属性时应特别小心,因为它可能会导致隐私和安全问题。确保你完全理解了这个属性的工作方式并合理使用。
- 如何在JavaScript中设置和读取Cookies?如果一个Cookie被设置为
HttpOnly
,这会发生什么?
如何在JavaScript中设置和读取Cookies?
在JavaScript中,可以使用document.cookie
属性来读取和设置cookies。
- 设置cookie:
document.cookie = "username=JohnDoe; expires=Thu, 18 Dec 2023 12:00:00 UTC; path=/";
这里,我们设置了一个名为 “username” 的cookie,其值为 “JohnDoe”,该cookie将在2023年12月18日12:00:00 UTC到期,并且它可在整个网站上使用(由于path=/
)。
- 读取cookie:
var allCookies = document.cookie;
这会返回一个字符串,其中包含所有为当前页面设置的cookies。你可能需要解析此字符串以获得特定的cookie值。
如果一个Cookie被设置为HttpOnly
,这会发生什么?
当一个cookie被设置为HttpOnly
时,它将不能被JavaScript脚本访问。这意味着,尽管该cookie仍然存在于客户端,且仍可以通过HTTP或HTTPS请求发送给服务器,但你无法使用例如document.cookie
的方法在浏览器端JavaScript代码中读取或修改它。
这个属性的主要目的是增加安全性,防止潜在的跨站脚本攻击(XSS)。在这样的攻击中,攻击者可能会尝试使用恶意脚本来读取用户的cookies,包括可能包含敏感信息或会话标识符的cookies。通过将cookie设置为HttpOnly
,我们可以有效地减少这种风险,因为即使恶意脚本运行在用户的浏览器上,它也无法访问这些标记为HttpOnly
的cookies。
-
解释第三方Cookies与第一方Cookies的区别。
-
为什么长时间的session cookies可能不是一个好主意?
-
什么是Cookie的域(Domain)和路径(Path)?它们如何影响Cookie的作用域?
-
在服务端,如何设置
HttpOnly
Cookie? -
为什么我们应该避免在Cookies中存储敏感信息,即使它们被设置为
HttpOnly
? -
描述Cookie的生命周期。怎样设置一个会话Cookie,以及一个持久性Cookie?
-
在Web应用程序中,Cookies与Session有什么区别和联系?
-
如何确保Cookies在不同的环境和浏览器中一致性地工作?
-
什么是Cookie的大小限制?如果你需要存储的信息超过了这个限制,你会如何处理?
9.说说跨站请求伪造(CSRF)攻击
CSRF 攻击简化流程:
-
目标:攻击者希望攻击某个受害者在网站
bank.com
上的账户,该受害者在bank.com
有登录状态。 -
建立陷阱:攻击者在一个他控制的网站
evil.com
上放置了一个恶意脚本或者构造了一个看起来正常的链接。这个链接或脚本其实是向bank.com
发送一个请求。例如:
<img src="https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fbank.com%2Ftransfer%3Fto%3Dattacker%26amount%3D1000&pos_id=img-kXng9Qhn-1694418053406)" width="0" height="0">
当受害者访问
evil.com
时,上述链接会尝试向bank.com
发起一个转账请求。 -
利用用户登录状态:如果受害者在
bank.com
处于登录状态,并且其浏览器还有bank.com
的 Cookie,这个请求就会带上这个 Cookie,因为浏览器会自动附带相应站点的 Cookie。从bank.com
的角度看,这个请求看起来是一个合法的用户请求。 -
完成攻击:如果
bank.com
没有进行 CSRF 保护,它会执行这个恶意请求,将受害者的钱转到攻击者的账户。
如何防范 CSRF 攻击:
-
使用 CSRF 令牌:为每个会话和请求生成一个随机的、不可预测的令牌。只有在收到正确的令牌时,服务器才会处理请求。
-
检查 Referer 标头:如果请求的来源不是预期的域(例如从
evil.com
来的请求),那么可以拒绝该请求。 -
强制重新认证:对于敏感的操作(如转账),要求用户再次输入密码或进行其他形式的二次认证。
我的问题:
cookie默认情况就是不跨域的,为什么受害者访问 evil.com 时点击了链接能发送bank.com 的 Cookie?
当我们提到 CSRF 攻击,其关键在于它是如何利用浏览器的自动行为进行的。
在 CSRF 攻击中,攻击者不会尝试直接读取 bank.com
的 Cookie,也不会尝试从 evil.com
创建或设置一个新的 Cookie 为 bank.com
。而是利用的是浏览器在用户请求特定站点时,自动将与该站点相关联的 Cookie 附加到请求上的特性。
详细解释一下:
- 用户先前登录了
bank.com
并获得了一个与其会话关联的 Cookie。 - 用户在另一个标签或窗口中访问了
evil.com
。 evil.com
包含一个使浏览器发起请求到bank.com
的恶意代码,如之前提到的<img src="https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fbank.com%2Ftransfer%3Fto%3Dattacker%26amount%3D1000&pos_id=img-kXng9Qhn-1694418053406)" width="0" height="0">
。- 当浏览器尝试加载上述
<img>
标签指向的 URL 时,它会自动地,按照设计,将与bank.com
相关的 Cookie 附加到这个请求上。这就是浏览器的正常行为。 - 这意味着,即使请求是从
evil.com
页面发起的,由于它是针对bank.com
的,浏览器仍然会附加与bank.com
相关的 Cookie。
这就是 CSRF 攻击的核心:它不是试图窃取或直接利用 Cookie,而是利用浏览器的这种自动行为来执行未经授权的操作。
10.浏览器的存储
浏览器提供了多种客户端存储机制,每种机制都有其特定的用途、特性和限制。以下是对 cookie
、localStorage
、sessionStorage
和 IndexedDB
的对比:
1. Cookie
- 存储大小: 通常限制为4KB。
- 生命周期: 可以设置过期时间。如果没有设置,它的生命周期将与会话持续相同,即关闭浏览器后会被删除。
- 与服务器交互: 每次HTTP请求都会附带,这可能会浪费带宽。
- 访问性: JavaScript可以访问,但需要考虑安全性(例如:设置
HttpOnly
标志以防止通过JS访问)。 - 使用场景: 适合小量数据的存储,经常用于身份验证(如存储JWT或会话ID)。
2. LocalStorage
- 存储大小: 通常限制为5-10MB。
- 生命周期: 没有过期时间,除非明确删除,否则数据会永久存储。
- 与服务器交互: 数据只在客户端存储,不会随每次请求发送给服务器。
- 访问性: 可以通过JavaScript访问。
- 使用场景: 适合大量持久化的数据,如用户偏好设置、主题等。
3. SessionStorage
- 存储大小: 通常限制为5-10MB。
- 生命周期: 数据在页面会话期间可用,关闭页面或浏览器后会被清除。
- 与服务器交互: 数据只在客户端存储,不会随每次请求发送给服务器。
- 访问性: 可以通过JavaScript访问。
- 使用场景: 适合需要在浏览器会话中临时存储的数据。
4. IndexedDB
- 存储大小: 无明确的限制,但可能受到磁盘空间的影响。通常可以存储大量数据。
- 生命周期: 没有过期时间,除非明确删除,否则数据会永久存储。
- 与服务器交互: 数据只在客户端存储,不会随每次请求发送给服务器。
- 访问性: 可以通过JavaScript访问。
- 结构: 它是一个事务性的数据库系统,可以存储键值对,支持索引,事务和游标。
- 使用场景: 适合大量数据的存储,如离线应用数据、大数据集等。
总结
- 大小:
cookie
<localStorage/sessionStorage
<<IndexedDB
- 生命周期:
sessionStorage
<cookie
(如果设置了过期时间) =localStorage
=IndexedDB
- 与服务器交互: 只有
cookie
会随HTTP请求自动发送。 - 结构: 只有
IndexedDB
提供了数据库的功能和结构。 - 用途: 根据存储需求和数据的大小、持续性来选择合适的存储机制。
11.HTTP与HTTPS、第三方证书工作原理、以及HTTP各个版本
HTTP各个版本
HTTP(Hypertext Transfer Protocol)和HTTPS(HTTP Secure)是用于在客户端和服务器之间传输数据的协议,它们在以下几个方面有所区别:
- 安全性:
- HTTP是明文协议,数据在传输过程中不加密,容易被窃取和篡改。而HTTPS通过使用SSL/TLS协议对数据进行加密,确保传输的数据是安全的,可以有效防止中间人攻击和数据泄露。
- HTTPS使用数字证书对数据进行数字签名,确保传输的数据在传输过程中没有被篡改或修改。客户端可以验证证书的合法性,确保与服务器建立的连接是可信的。
- 默认端口:HTTP使用80端口进行通信,而HTTPS使用443端口进行通信。
对于第三方证书如何保证服务器的可信性,这涉及到公开密钥基础设施(PKI)的工作原理。具体步骤如下:
-
服务器生成密钥对:服务器首先生成一个密钥对,包括公钥和私钥。
-
证书请求:服务器将公钥发送给受信任的第三方机构(证书颁发机构,CA),请求颁发证书。
-
验证身份:证书颁发机构验证服务器的身份。
-
颁发证书:一旦服务器的身份验证通过,证书颁发机构会生成证书并将其签名。证书中包含了服务器的公钥以及其他相关信息。
-
客户端验证:当客户端与服务器建立HTTPS连接时,服务器会将证书发送给客户端。客户端会验证证书的合法性,包括检查证书的签名、过期时间、颁发机构等。
-
可信根证书:客户端会使用自己内置的受信任的根证书(Root CA)来验证服务器证书的合法性。如果证书链可以追溯到受信任的根证书,且没有被撤销或过期,客户端会信任服务器的证书。
12.怎么传递引用类型而互不影响 ?(深拷贝)
当传递引用类型(如对象、数组)时,你实际上是传递了一个指向原始数据的指针或引用。因此,如果你修改了传递后的引用,原始数据也会受到影响。为了避免这种情况,你可以进行“深复制”或“深克隆”以创建原始数据的一个完整副本,这样原始数据和副本之间就不会相互影响。
以下是一些常用方法来传递引用类型并确保它们互不影响:
-
使用 JSON 方法:
这是一个简单的方法,但有局限性(例如,它不能处理函数、undefined
、正则表达式或新的数据类型如Map
和Set
)。var original = { a: 1, b: { c: 2 } }; var copy = JSON.parse(JSON.stringify(original));
-
使用递归方法进行深克隆:
function deepClone(obj, hash = new WeakMap()) {if (obj == null) return obj; // 如果是null或undefined,直接返回if (obj instanceof RegExp) return new RegExp(obj);if (obj instanceof Date) return new Date(obj);if (hash.has(obj)) return hash.get(obj); // 防止循环引用let t = new obj.constructor();hash.set(obj, t);for (let key in obj) {if (obj.hasOwnProperty(key)) {t[key] = deepClone(obj[key], hash);}}return t; }var original = { a: 1, b: { c: 2 } }; var copy = deepClone(original);
-
使用第三方库:
例如,lodash 提供了一个cloneDeep
方法,可以用来进行深克隆。var _ = require('lodash'); var original = { a: 1, b: { c: 2 } }; var copy = _.cloneDeep(original);
这些方法可以确保你传递的引用类型数据互不影响。但在使用时,你应该考虑到深克隆可能会比浅克隆或直接传递引用更加耗时,尤其是在处理大数据结构时。
13.静态多态
在前端面试中,"静态多态"是一个常见的概念,通常与面向对象编程(Object-Oriented Programming,简称OOP)相关。
静态多态(Static Polymorphism)也被称为编译时多态或早期绑定(Early Binding),它是在编译时确定方法调用的一种特性。在静态多态中,方法重载是最常见的应用形式。
方法重载是指在同一个类中定义多个具有相同名称但参数列表不同的方法。通过重载,可以根据传递给方法的参数的类型、数量或顺序来决定具体调用哪个方法。这种静态多态性是通过编译器在编译时根据方法的签名来确定的。
静态多态的一个示例是在前端开发中使用的函数重载。在JavaScript中,函数重载是一种模拟静态多态的技术,因为JavaScript不直接支持方法重载。通过在函数内部根据参数的类型和数量进行条件判断,可以实现不同的函数行为。
下面是一个简单的JavaScript函数重载示例:
function add(x, y) {return x + y;
}function add(x, y, z) {return x + y + z;
}console.log(add(2, 3)); // 输出 5
console.log(add(2, 3, 4)); // 输出 9
在上面的例子中,通过定义两个同名但参数个数不同的函数add
,实现了根据参数个数的不同来执行不同的加法操作。
总结来说,静态多态是指在编译时根据方法的签名来确定方法调用的特性。在前端开发中,函数重载是一种模拟静态多态的技术,可以根据参数的类型、数量或顺序来实现不同的函数行为。
14.怎么用js实现类的修饰符 private public
在 JavaScript 中,从 ES6(ES2015)开始,我们可以使用类(classes)来定义对象的结构和方法。但是,直到 ES2020,JavaScript 的类并没有提供原生的 private
或 public
修饰符。ES2020 为类引入了真正的私有字段和方法,这为 JavaScript 开发者提供了一种确保数据封装和私有状态的方式。
以下是如何在 JavaScript 中使用 private
和 public
修饰符:
-
public(默认情况下)
所有没有使用任何修饰符的属性和方法默认都是公有的。你不需要显式地标注它们为
public
。class MyClass {publicField = "I'm public!"; // public by defaultpublicMethod() {console.log("Hello from a public method!");} }const instance = new MyClass(); console.log(instance.publicField); // I'm public! instance.publicMethod(); // Hello from a public method!
-
private
在属性或方法的名称前使用
#
可以将其标记为私有。私有字段或方法不能从类的外部访问。class MyClass {#privateField = "I'm private!";#privateMethod() {console.log("Hello from a private method!");}accessPrivate() {console.log(this.#privateField);this.#privateMethod();} }const instance = new MyClass(); // console.log(instance.#privateField); // Error! Private field // instance.#privateMethod(); // Error! Private method instance.accessPrivate(); // This will access the private field and method
注意,真正的私有类字段和方法在旧的浏览器或 JavaScript 环境中可能不受支持。在使用前,请确保你的目标环境支持 ES2020 或更高版本的功能。
15.前端如何性能优化
前端性能优化是提高网页加载速度和响应性能的关键方面。以下是一些常见的前端性能优化技巧:
-
减少 HTTP 请求:减少网页需要发送的 HTTP 请求次数,可以通过合并和压缩文件、使用 CSS 精灵图、减少第三方库和插件的使用等方式来实现。
-
压缩文件:压缩 CSS、JavaScript 和 HTML 文件,可以减小文件大小,加快下载速度。可以使用压缩工具(如UglifyJS、CSSNano等)或使用构建工具(如Webpack、Gulp)进行文件压缩。
-
使用浏览器缓存:通过设置适当的缓存头(Cache-Control、Expires等),使得浏览器可以缓存静态资源,减少不必要的请求和下载。
-
图片优化:对图片进行优化,包括压缩图片大小、选择合适的图片格式(如JPEG、PNG、WebP)以及使用图片懒加载等技术来减少页面加载时间。
-
延迟加载:延迟加载非关键内容,如图片、视频、广告等,可以通过懒加载技术(如Intersection Observer API)来实现,以提高初始页面加载速度。
-
代码优化:优化 JavaScript 和 CSS 代码,包括删除不必要的注释和空格、减少重绘和重排、避免不必要的计算和循环等,以提高执行效率。
-
使用 CDN:将静态资源(如图片、CSS、JavaScript文件)托管到内容分发网络(CDN)上,可以提高资源加载速度,减少服务器负载。
-
预加载和预渲染:使用预加载(Preload)和预渲染(Prerender)技术,提前加载和渲染关键资源和页面,以加快用户访问体验。
-
响应式设计:采用响应式设计,使网页能够适应不同屏幕尺寸和设备,提供更好的用户体验。
-
代码分割和按需加载:将大型应用程序拆分为小模块,并按需加载,以避免不必要的资源加载和初始化,提高页面加载速度。
-
监测和分析:使用工具(如Lighthouse、WebPageTest、Google Analytics等)监测和分析网页性能,找出性能瓶颈,并针对性地进行优化。
以上是一些常见的前端性能优化技巧,具体的优化策略和技术选择应根据项目需求和实际情况进行评估和实施。重要的是不断测试和测量优化的效果,并进行持续改进。
进程和线程
七层模型、五层模型
deffer\async 加载js
Http、Https
深度优先遍历和广度优先遍历
diff算法
安全性相关
react原理fiber调度算法
相关文章:
浏览器面试题
浏览器面试题 1.常见的浏览器内核有哪些?2.浏览器的主要组成部分有哪些?3.说一说从输入URL到页面呈现发生了什么?4.浏览器重绘域重排的区别?5.CSS加载会阻塞DOM吗?6.JS会阻塞页面吗?7.说一说浏览器的缓存机…...
Java Controller层异常处理示例【含面试题】
AI绘画关于SD,MJ,GPT,SDXL百科全书 面试题分享点我直达 2023Python面试题 2023最新面试合集链接 2023大厂面试题PDF 面试题PDF版本 java、python面试题 项目实战:AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI…...
通过Git Bash将本地文件上传到本地github
1. 新建一个仓库( Repository) 1.1登录Github,点击个人头像,点击Your repositories,点击New。 1.2 填写信息 Repository name: 仓库名称 Description(可选): 仓库描述介绍,不是必填项目。~~建议填写上哦!…...
继承的笔记
继承 对象代表什么, 就得封装对应的数据, 并提供数据对应的行为 对于两种不同的类, 但是具有很多共同的属性的时候我们就想着用继承, 我们可以将共同的属性放置在一个类中, 然后, 只需要新建两个类, 继承共有的类, 然后单独写自己的属性特点 继承类 Java 中提供了一个关键字…...
Android7.1 ROOT权限的获取
修改文件: system/extras/su/su.c system/core/include/private/android_filesystem_config.h system/core/libcutils/fs_config.c frameworks/base/core/jni/com_android_internal_os_Zygote.cpp frameworks/base/cmds/app_process/app_main.cpp device/qcom…...
几个好用的数据标注软件labelme、CVAT及LabelImage
我们使用yolov3、yolov4、yolov5、yolov8等训练自己的权重时,需要有大量标注好的数据集,这里有几个好用的数据标注软件labelme、CVAT及LabelImage 一、labelme labelme:https://github.com/wkentaro/labelme 这个软件用的比较多,…...
VSCode学习笔记一:添加代码模板
一目了然 1 简述2 设置模板3 Global Snippets file示例 1 简述 问:为什么要设置代码模板? 答:编程语言是有个性的,不同语言的演讲风格是不一样的。 旁白:我不懂?! 问:为什么要设置…...
Linux下修改jar包中的配置文件application.conf
文件位置 jar包文件工程目录 打包后解压jar包目录 提取和上传 jar tf XXX.jar # 获取包内文件 application.conf是jar包的配置文件,如果修改需要 提取文件 jar xf my-app.jar application.conf 修改后上传文件 jar uf my-app.jar application.conf...
【python绘图—colorbar操作学习】
文章目录 Colorbar的作用Colorbar的操作截取cmap拼接cmap双刻度列colorbar 引用 Colorbar的作用 Colorbar(颜色条)在绘图中的作用非常重要,它主要用于以下几个方面: 表示数据范围: Colorbar可以显示图中的颜色映射范围…...
Python+Appium自动化测试-编写自动化脚本
之前已经讲述怎样手动使用appium-desktop启动测试机上的app,但我们实际跑自动化脚本的过程中,是需要用脚本调用appium启动app的,接下来就尝试写Python脚本启动app并登陆app。环境为Windows10 Python3.7 appium1.18.0 Android手机 今日头条…...
AMEYA360|ROHM罗姆首次推出硅电容器BTD1RVFL系列
全球知名半导体制造商ROHM(总部位于日本京都市)新开发出在智能手机和可穿戴设备等领域应用日益广泛的硅电容器。利用ROHM多年来积累的硅半导体加工技术,新产品同时实现了更小的尺寸和更高的性能。 随着智能手机等应用的功能增加和性能提升,业界对于支持更…...
Linux发散小知识
linux/unix哲学:KISS Keep It Simple and Stuid。 "提供一套机制,而不是策略",“万般皆文本,四处用脚本” unix的数据流追求简单化、通用性、可视性、设备无关,二进制肯定无法做到这些,因此文本…...
GTS 中testPeakPssOfAllApps fail 详解
0. 前言 GTS 在测试 case armeabi-v7a GtsMemoryHostTestCases 的时候出现下面异常,本文总结一下。 com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps 1. error log 09-14 10:16:34 I/TestFailureListener: FailureListener.testFaile…...
linux查看远程仓库的分支
在 Linux 终端中,您可以使用 git 命令来查看远程仓库的分支。git 是版本控制系统,用于管理代码的版本和协作开发。以下是查看远程仓库分支的方法: 查看所有远程分支: git ls-remote <remote_repository_url> 这个命令会显示…...
【Linux常用命令】
编程不良人 Linux 笔记 一、防火墙相关 1、查看防火墙状态 systemctl status flrewalld2、如果防火墙是开启状态的,需要关闭 systemctl stop firewalld3、永久行关闭操作(禁止开机自启动) 因为防火默认是开启状态的,如果只是手…...
QString类与整型,浮点数互转
本文介绍QString类与整型,浮点数之间的相互转换。 1.QString类转整型 QString类转整型(包含2进制,8进制,16进制),可以使用QString的toInt()函数。 QString str("1234"); bool bOK false; int…...
基于STM32F407ZET6的环境温湿度监控系统(粤嵌GEC-M4)
注意使用事项: 开发板如下 由于外部晶振是8M,需要修改setup和stm32f4头文件的晶振值。 操作如下: system_stm32f4xx.c的254行 #define PLL_M 8stm32f4xx.h的127行 #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the Ex…...
2023年五一杯数学建模A题无人机定点投放问题求解全过程论文及程序
2023年五一杯数学建模 A题 无人机定点投放问题 原题再现: 随着科学技术的不断发展,无人机在许多领域都有着广泛的应用。对于空中执行定点投放任务的无人机,其投放精度不仅依赖于无人机的操作技术,而且还与无人机执行任务时所处状…...
Redis 7 第九讲 微服务集成Redis 应用篇
Jedis 理论 Jedis是redis的java版本的客户端实现,使用Jedis提供的Java API对Redis进行操作,是Redis官方推崇的方式;并且,使用Jedis提供的对Redis的支持也最为灵活、全面;不足之处,就是编码复杂度较高。 …...
c++day7
仿照vector手动实现自己的myVector,最主要实现二倍扩容功能 #include <iostream>using namespace std; template <typename T> class Myvector { private:T *start;//起始指针T *end;//数组末尾指针T *last;//数组有效长度的尾指针 public://定义无参构…...
C++学习概述
1.c 为啥需要头文件 如果您刚开始使用 C,您可能想知道为什么C需要 #include 头文件,以及为什么一个程序要拥有多个 .cpp 文件。 原因很简单: a) 减少编译时间 随着程序的增长,您的代码也会增长,如果所有内容都在一个…...
关系型数据库和非关系型数据库
关系型数据库和非关系型数据库 关系型数据库非关系型数据库 非关系型数据库和关系型数据库是两种不同类型的数据库管理系统,它们用于存储和管理数据,但在数据组织和处理方式上有一些重要的区别。 关系型数据库 1.结构化数据存储:关系型数据库…...
基于SSM的快餐店点餐服务系统设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...
使用vcpkg配置CGAL+visual studio 2022
先安装vcpkg C:\dev> git clone https://github.com/microsoft/vcpkg C:\dev> cd vcpkg C:\dev\vcpkg> .\bootstrap-vcpkg.bat 运行后,先执行 C:\dev\vcpkg> .\vcpkg.exe install yasm-tool:x86-windows 这是因为gmp库中有个bug,只能这样…...
【Spring面试】三、Bean的配置、线程安全、自动装配
文章目录 Q1、什么是Spring Bean?和对象有什么区别Q2、配置Bean有哪几种方式?Q3、Spring支持的Bean有哪几种作用域?Q4、单例Bean的优势是什么?Q5、Spring的Bean是线程安全的吗?Q6、Spring如何处理线程并发问题…...
flink连接kafka报:org.apache.kafka.common.errors.TimeoutException
测试flink1.12.7 连接kafka: package org.test.flink;import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutio…...
sql order by 排序 null值放最后,怎么写
在 SQL 中,可以使用 ORDER BY 子句对结果进行排序。如果要将 NULL 值放在最后,可以在排序列中使用 CASE 表达式来处理。 下面是一个示例查询,将 NULL 值放在最后进行排序: SELECT column1, column2 FROM your_table ORDER BY CAS…...
HDMI字符显示实验
FPGA教程学习 第十五章 HDMI字符显示实验 文章目录 FPGA教程学习前言实验原理程序设计像素点坐标模块字符叠加模块 实验结果知识点总结 前言 在HDMI输出彩条的基础上输出osd叠加信息。 实验原理 实验通过字符转换工具将字符转换为 16 进制 coe 文件存放到单端口的 ROM IP 核…...
Spring Cloud 框架搭建
Spring Cloud 框架搭建之一基础框架 创建父项目创建子项目 创建父项目 第一步:新建项目,填写基础信息 第二步:这里不需要其他组件直接点next即可。 第三步:pom文件添加下述代码,将父项目设置为pom文件形式打包&#…...
20个非常有用的单行Python代码片段
1. 写在前面 继上篇,继续在本文分享 20 个 Python 单行代码,可以在 30 秒或更短时间内轻松学会。这些单行代码不仅可以提高效率,同时使代码看起来更整洁、更易读。:) 个人博客: https://jianpengzhang.git…...
奶茶店加盟网站建设/网页模板代码
简单看了下楼主说的很详细,尤其是最后面那个图描述很直观,让想学习ISO开发的程序猿很清晰每个步骤学习的内容,在此收藏下。 iOS系统以及iPhone的出来都要感谢乔布斯,一个完美主义者,从如此优秀的iOS系统和iPhone就可以…...
网站建设 网络推广/合肥网络优化公司有几家
问题: vue2.的项目在360急速浏览器上运行空白,结果输出360极速浏览器内核是ie11 -.-!!! 难怪!!! 简单直接一点: 在项目的index.html里面直接引入: <script src"https://cdn.bootcss.co…...
怎么给客户谈做网站/seo方法培训
今天我们来聊聊MySQL中InnoDB存储引擎的锁。锁是数据库系统系统区别于文件系统的一个关键特性。lock和 latchlatchlatch在MySQL中是用来保证并发多线程操作操作临界资源的锁,锁定的对象线程,是和咱们使用的Java等传统语言中的锁意义相近,而且…...
电子商务网站建设与规划/域名查询网
导读: .Net提供了许多多线程编程工具,可能是因为太多了,所以掌握起来总是有一些头疼,我在这里讲讲我总结的一些多线程编程的经验,希望对大家有帮助 不需要传递参数,也不需要返回参数 我们知道启动一个线程最直观的办法是使用Thread类,具体步骤如下 ThreadStart thre…...
有人模仿qq音乐做的h5网站吗/百度网盘网页版登录
用产品的思维去生活。 把自己的生活看成构建产品的一个过程,生活中的每个细节就是打磨产品的各个过程。 生活中各种物品的摆放考验这个一个产品经理的美学鉴赏力。 在2019年微信的一次公开课上,微信的缔造者张小龙发表了4小时的演讲。有网友做了统计&…...
高端广告公司名字/重庆旅游seo整站优化
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 流式语音合成 python3 sdk 下载地址、python2 sdk 下载地址。 接口请求域名:tts.cloud.tencent.…...