前端面试题详解整理30|性能优化字符串字母去重,事件捕获冒泡,跨域方案,XSS 和 CSRF 攻击场景jsonp 原理,

32 阅读12分钟

【前端校招面经】快手2023春招前端一面面经

base: bj

岗位: 前端开发, 校招

业务: 电商

之前投本地生活业务 HR 面挂了, 这次是复活赛

  • 自我介绍和项目经历

事件捕获和事件冒泡机制

事件捕获和事件冒泡是 DOM 事件传播过程中的两种不同的机制。

事件捕获(Event Capturing)

事件捕获是指事件从文档的根节点开始向下传播至触发事件的目标元素的过程。在事件捕获阶段,事件会依次从外层元素向内层元素传播,直到达到触发事件的目标元素。因此,在事件捕获阶段,事件会首先被触发元素的最外层祖先元素捕获,然后逐级向下传播。

事件冒泡(Event Bubbling)

事件冒泡是指事件从触发事件的目标元素开始向上传播至文档的根节点的过程。在事件冒泡阶段,事件会从触发事件的目标元素开始,逐级向上传播至外层祖先元素,直至达到文档的根节点。

DOM 事件传播过程中,事件首先经过捕获阶段,然后进入目标阶段,最后进入冒泡阶段。因此,事件捕获和事件冒泡是相对应的两种阶段,它们共同构成了 DOM 事件传播的完整过程。

在实际开发中,我们可以通过事件监听器的第三个参数来控制事件是在捕获阶段还是冒泡阶段触发,默认情况下,大部分事件都是在冒泡阶段触发。例如:

element.addEventListener('click', handler, true); // 第三个参数为 true 表示在捕获阶段触发事件
element.addEventListener('click', handler, false); // 第三个参数为 false(默认值)表示在冒泡阶段触发事件

通过理解事件捕获和事件冒泡机制,我们可以更好地控制和处理 DOM 事件,实现更加灵活和高效的交互效果。

前端有哪些跨域方案

前端常见的跨域方案包括以下几种:

  1. CORS(跨域资源共享):CORS 是一种官方的跨域解决方案,通过服务器端设置响应头来控制是否允许跨域请求。在客户端发起跨域请求时,浏览器会先发送一个 OPTIONS 预检请求,服务器返回响应头中包含 Access-Control-Allow-Origin、Access-Control-Allow-Methods 等字段,浏览器根据响应头的配置决定是否允许跨域请求。

  2. JSONP(JSON with Padding):JSONP 是一种通过 <script> 标签实现的跨域请求方式,它利用了浏览器对 <script> 标签的跨域请求特性来实现数据传输。但是 JSONP 只支持 GET 请求,且存在安全性问题,容易受到 XSS 攻击。

  3. 代理服务器:前端可以通过自建代理服务器来转发请求,将跨域请求发送到同源服务器,再由代理服务器转发给目标服务器。这种方式可以避免跨域问题,但需要额外的服务器资源。

  4. 反向代理:类似于代理服务器,但是反向代理是由目标服务器配置的代理服务器,可以将客户端的请求转发到不同的服务器上,并将响应返回给客户端。通过反向代理,可以实现在客户端看来是同源的请求。

  5. iframe + postMessage:通过在不同域的 iframe 中加载页面,并使用 postMessage 方法在不同窗口间传递数据,从而实现跨域通信。这种方式需要目标页面支持 postMessage,并且需要在不同窗口间建立信任关系。

  6. WebSocket:WebSocket 是一种全双工通信协议,可以在不同域之间建立持久连接,实现实时通信。WebSocket 需要服务器端支持,并且可以通过跨域策略文件(Crossdomain.xml)来配置允许的跨域请求。

以上是一些常见的前端跨域方案,选择合适的跨域解决方案取决于具体的业务需求和安全考虑。

jsonp 原理

JSONP(JSON with Padding)是一种跨域数据请求的解决方案,其原理是利用 <script> 标签的跨域特性来实现数据的传输。

JSONP 的工作原理如下:

  1. 前端页面中通过一个 <script> 标签向服务器发送一个 GET 请求,请求的 URL 包含一个回调函数的名称作为参数。

  2. 服务器接收到请求后,解析 URL 中的回调函数名称,并将需要返回的数据作为参数传递给该回调函数。

  3. 服务器将数据包装在回调函数中,并作为 JavaScript 代码返回给前端页面。

  4. 前端页面接收到返回的 JavaScript 代码后,浏览器会立即执行该代码,从而触发回调函数,并将服务器返回的数据作为参数传递给回调函数。

由于 JSONP 是通过 <script> 标签加载外部 JavaScript 脚本的方式来实现数据传输的,因此它具有跨域请求的能力。但是需要注意的是,JSONP 只支持 GET 请求,且由于安全性方面的考虑,需要对返回的数据进行信任验证,防止被注入恶意代码。

虽然 JSONP 在一定程度上解决了跨域请求的问题,但它也存在一些安全性和限制性方面的问题,例如只能发送 GET 请求、无法处理复杂的数据格式等,因此在实际应用中,可以考虑使用更安全、更灵活的跨域请求解决方案,如 CORS(跨域资源共享)。

XSS 和 CSRF 攻击场景列举

下面是关于 XSS(跨站脚本攻击)和 CSRF(跨站请求伪造)攻击的一些常见场景示例:

XSS 攻击场景

  1. 存储型 XSS:攻击者向网站提交包含恶意脚本的数据,然后其他用户访问该页面时执行恶意脚本。例如,攻击者在论坛或评论中插入恶意脚本,当其他用户访问时,恶意脚本会在其浏览器中执行。

  2. 反射型 XSS:攻击者构造一个包含恶意脚本的 URL,诱使用户点击该 URL,触发恶意脚本执行。例如,通过电子邮件或社交媒体等方式发送带有恶意脚本的链接,用户点击后被攻击。

  3. DOM 型 XSS:攻击者通过修改页面的 DOM 结构,将恶意脚本注入到页面中,然后用户访问带有恶意脚本的页面时,恶意脚本会在其浏览器中执行。例如,通过修改 URL 参数或表单提交数据来触发恶意脚本执行。

CSRF 攻击场景

  1. 银行转账:用户在网银或支付宝等平台登录后,攻击者诱使用户点击一个链接,该链接发起了一笔转账请求,由于用户已经登录,所以请求会被当作合法请求处理,导致用户的资金被转走。

  2. 修改用户资料:攻击者构造一个恶意网站,在网站中包含一个表单,表单会向目标网站发起修改用户资料的请求,如果用户已经登录目标网站,那么该请求会被当作合法请求处理,导致用户的资料被恶意修改。

  3. 利用已登录状态:用户在社交媒体或其他网站上已经登录,攻击者诱使用户点击一个链接或访问一个页面,页面中包含一个自动提交的表单或 AJAX 请求,这些请求会利用用户的登录状态在目标网站上执行一些恶意操作,例如发布垃圾信息、删除内容等。

这些场景只是一小部分可能发生的情况,但它们都展示了 XSS 和 CSRF 攻击的原理和危害。为了防范这些攻击,开发人员需要采取一系列安全措施,包括输入验证、输出编码、安全头部设置、CSRF 令牌等。

假如黑客注入一个恶意脚本, 发出了一条 ajax 请求, 该请求发送到黑客自己的服务器然后进行一个转发, 这种场景是否属于 CSRF?

不,这种情况不属于 CSRF(跨站请求伪造)攻击。

CSRF 攻击是指黑客利用用户已登录的身份在用户不知情的情况下发送恶意请求,通常是通过伪装成合法请求的形式进行攻击。攻击者诱使用户在已登录的状态下访问包含恶意代码的网站,从而触发恶意请求。

在描述的情况中,虽然黑客注入了恶意脚本并发起了一条 AJAX 请求,但该请求并不是通过用户的身份进行的。相反,请求是通过注入的脚本发起的,无论用户是否已登录,请求都会被发送到黑客自己的服务器并进行转发。因此,这种情况不符合 CSRF 攻击的定义。

然而,虽然不是 CSRF 攻击,但这种注入恶意脚本的行为可能会导致其他安全问题,例如 XSS(跨站脚本攻击)攻击,因为用户在访问受影响的网页时可能会执行恶意脚本。因此,保护网站免受恶意脚本注入是非常重要的安全措施之一。

  • 代码题: 事件循环看代码说结果

代码题: 实现字符串字母去重, 但不区分大小写

要实现字符串字母去重且不区分大小写,可以使用 JavaScript 中的 Set 数据结构。Set 是一种集合,它只存储唯一的值,可以轻松地用于去重操作。同时,我们可以先将字符串转换为统一的大小写,再进行去重操作。

以下是实现的代码示例:

function removeDuplicateLetters(str) {
    // 将字符串统一转换为小写
    str = str.toLowerCase();
    // 使用 Set 去重
    const uniqueChars = new Set(str);
    // 将 Set 转换为数组并重新组合成字符串
    const result = [...uniqueChars].join('');
    return result;
}

// 示例测试
console.log(removeDuplicateLetters("Hello World")); // 输出: "helo wrd"
console.log(removeDuplicateLetters("aabbcc")); // 输出: "abc"
console.log(removeDuplicateLetters("AaAaBbB")); // 输出: "ab"

以上代码首先将输入字符串统一转换为小写,然后使用 Set 去重,最后将去重后的字符数组重新组合成字符串返回。这样就可以实现字符串字母去重且不区分大小写的功能。

  • 前端有哪些性能优化手段? 假如说你的用户和你距离很远, 你无法在用户的终端复现他的卡顿场景, 你怎么排查

前端性能优化是一个复杂而广泛的话题,涉及到各个方面的优化策略。以下是#

一些常见的前端性能优化手段:

  1. 减少 HTTP 请求次数:合并和压缩 JavaScript、CSS 文件,使用 CSS 精灵,减少页面图片数量等,从而减少页面加载时需要的 HTTP 请求次数。

  2. 使用 CDN 加速:将静态资源(如图片、CSS、JavaScript 文件)托管到 CDN 上,利用 CDN 的分布式网络加速内容传输,提高页面加载速度。

  3. 优化图片:使用适当的图片格式(如 WebP、JPEG2000 等)和压缩技术,减小图片大小,提高页面加载速度。

  4. 延迟加载:使用懒加载技术,仅在用户需要时才加载页面上的某些部分或资源,减少初始页面加载时间。

  5. 缓存优化:合理利用浏览器缓存和服务器缓存,减少重复请求,提高页面访问速度。

  6. DOM 操作优化:减少 DOM 操作的频率和复杂度,尽量减少重排和重绘,优化 JavaScript 代码性能。

  7. 资源预加载:提前加载用户可能需要的资源,加快用户访问速度。

  8. 代码拆分和懒加载:将大型 JavaScript 应用拆分为多个模块,并使用动态导入(Dynamic Import)或懒加载技术按需加载,减少初始加载时间。

  9. 服务端渲染(SSR):使用服务器端渲染技术生成 HTML 页面,减少客户端渲染时间,提高页面首屏加载速度。

当无法复现用户卡顿场景时,可以尝试以下排查方法:

  1. 性能分析工具:使用浏览器的开发者工具或者第三方性能分析工具(如 Lighthouse、WebPageTest 等)对页面性能进行全面的分析,找出性能瓶颈。

  2. 监控系统:使用监控系统(如 Google Analytics、Sentry 等)实时监测页面性能和用户行为,收集异常和性能数据,及时发现问题。

  3. 用户反馈:收集用户反馈和投诉,了解用户在页面加载和交互过程中遇到的问题和体验不佳的地方,从而找出可能的性能问题。

  4. 网络条件模拟:使用网络模拟工具(如 Chrome DevTools 中的网络节流功能)模拟不同网络条件下的页面加载情况,了解在不同网络环境下页面的加载性能。

综上所述,通过性能分析工具、监控系统、用户反馈和网络条件模拟等方法,可以辅助排查用户远程卡顿场景下的性能问题,找出并解决页面性能瓶颈。

作者:四季奶青大杯正常糖
链接:www.nowcoder.com/discuss/480…
来源:牛客网