首页 > 其他分享 >前端-深入了解前端

前端-深入了解前端

时间:2024-09-12 11:35:24浏览次数:1  
标签:脚本 setTimeout 前端 任务 了解 深入 Promise 执行 CSP

JavaScript的Event Loop概念

JavaScript 的 Event Loop(事件循环)是其执行模型的核心机制,确保了异步操作和事件的处理能够在单线程环境下顺利进行。让我们详细解释 Event Loop 的工作原理,并探讨在 setTimeoutPromise 同时存在时,谁先执行。

Event Loop 的工作原理

  1. 调用栈(Call Stack):

    • JavaScript 使用调用栈来执行代码。当函数被调用时,它会被推入栈中,函数执行完毕后会从栈中弹出。
  2. 任务队列(Task Queue / Callback Queue):

    • 任务队列存储需要被执行的异步任务。常见的任务有 setTimeoutsetInterval 和 I/O 事件处理等。
  3. 微任务队列(Microtask Queue / Job Queue):

    • 微任务队列主要用于处理 Promise 的回调函数。微任务具有比宏任务(如 setTimeout)更高的优先级。
  4. 事件循环(Event Loop):

    • 事件循环不断检查调用栈是否为空。如果调用栈为空,事件循环会从任务队列中取出任务执行。

setTimeout 和 Promise 的执行顺序

在 JavaScript 中,当 setTimeoutPromise 同时存在时,它们的执行顺序受以下因素影响:

  1. 宏任务(Macrotask):

    • setTimeout 属于宏任务。宏任务在任务队列中执行,并且在每次事件循环的宏任务阶段执行。
  2. 微任务(Microtask):

    • Promise 的回调函数(如 thencatchfinally)属于微任务。微任务会在当前任务执行完成后,调用栈为空时立即执行。

执行顺序

  1. 同步代码:

    • 直接在调用栈中执行。
  2. 微任务:

    • 在当前同步代码执行完毕后,且在任何宏任务之前,微任务会被执行。
  3. 宏任务:

    • 之后会处理宏任务队列中的任务,如 setTimeout

示例代码

javascript复制代码
console.log('Start');

setTimeout(() => {
    console.log('Timeout');
}, 0);

Promise.resolve().then(() => {
    console.log('Promise');
});

console.log('End');

解释:

  1. console.log('Start') 被立即执行。
  2. setTimeout 回调函数被设置为 0 毫秒后执行,并且会被添加到宏任务队列中。
  3. Promise.resolve().then 的回调函数被添加到微任务队列中。
  4. console.log('End') 被立即执行。

执行顺序:

  1. console.log('Start') - 立即执行。
  2. console.log('End') - 立即执行。
  3. 微任务(Promise) - 在当前执行上下文完成后,微任务会被处理,打印 Promise
  4. 宏任务(setTimeout) - 微任务执行完后,事件循环会处理宏任务,打印 Timeout

所以,Promise 的回调函数会在 setTimeout 的回调函数之前执行,即使 setTimeout 的延迟时间设置为 0 毫秒。微任务总是会在宏任务之前执行,这是 Event Loop 的设计决定的。

总结

  • Event Loop 确保了 JavaScript 的异步操作能够在单线程环境下正确执行。
  • 微任务(如 Promise 的回调)优先于 宏任务(如 setTimeout)执行。
  • 当 setTimeout 和 Promise 同时存在时,Promise 的回调会先于 setTimeout 的回调执行。

 

setTimout中执行死循环和promise.then执行死循环哪个会卡死

都会卡死,两者的主要区别在于它们的任务队列优先级和影响范围:

  1. setTimeout 中的死循环:

    • 优先级:setTimeout 的回调属于宏任务队列。宏任务在微任务(Promise.then)之后执行。
    • 影响:当主线程在执行 setTimeout 回调中的死循环时,所有其他宏任务和微任务都会被延迟,直到当前的宏任务(即死循环)完成。
  2. Promise.then 中的死循环:

    • 优先级:Promise.then 的回调属于微任务队列。微任务在当前执行栈完成后、下一个宏任务之前执行。
    • 影响:当主线程在执行 Promise.then 回调中的死循环时,所有微任务会被阻塞,因此后续的微任务和宏任务(如 setTimeout)也会被延迟,直到当前的微任务(即死循环)完成。

简单来说,setTimeout 中的死循环会影响所有的任务,包括微任务和宏任务,但 Promise.then 中的死循环主要影响微任务的执行,并间接影响宏任务的开始。

 什么是CSP

Content Security Policy (CSP) 通过定义明确的资源加载策略来防止 XSS(跨站脚本攻击)。它的核心思想是限制网页能够从哪些来源加载资源,如脚本、样式、图片等。以下是 CSP 如何实现防止 XSS 的具体机制:

1. 限制脚本来源

CSP 允许开发者指定哪些来源的脚本可以被加载和执行。这通过 script-src 指令来实现。例如:

http复制代码
Content-Security-Policy: script-src 'self'

这条策略表示只允许从当前网站加载脚本。其他来源(例如,外部广告脚本、第三方分析脚本)将被禁止,从而减少了 XSS 攻击的可能性。

2. 禁用内联脚本和事件处理器

CSP 可以通过禁用内联脚本和内联事件处理器来防止攻击者通过注入恶意脚本来执行 XSS 攻击。通过使用 'strict-dynamic''nonce-<random>''hash-<base64>',可以防止未授权的内联脚本执行。

  • 'nonce-<random>':允许只有在页面生成时设置的特定 nonce 值的脚本执行。例如:

    html复制代码
    <script nonce="random123">console.log('safe script');</script>
    

    CSP 头部设置为:

    http复制代码
    Content-Security-Policy: script-src 'self' 'nonce-random123'
    
  • 'strict-dynamic':允许在加载脚本时,只有在严格模式下(如来自授权来源的脚本)才执行该脚本。这会进一步限制未被授权的脚本的执行。

3. 限制样式来源

类似于脚本的限制,CSP 允许限制样式表的来源,通过 style-src 指令。例如:

http复制代码
Content-Security-Policy: style-src 'self'

这条策略会阻止加载来自未授权来源的样式表,减少了 CSS 中可能存在的 XSS 漏洞。

4. 阻止不安全的资源

CSP 可以阻止加载不安全的资源,如不加密的 HTTP 请求。通过设置 upgrade-insecure-requests 指令,所有的 HTTP 请求会被自动升级为 HTTPS,减少中间人攻击的风险:

http复制代码
Content-Security-Policy: upgrade-insecure-requests

5. 资源完整性检查

CSP 允许开发者为脚本和样式定义哈希值或使用 integrity 属性进行完整性检查。这确保了加载的资源未被篡改。

6. 防止数据注入

通过 frame-ancestors 指令,可以指定允许嵌套页面的来源,这有助于防止点击劫持攻击(clickjacking)。例如:

http复制代码
Content-Security-Policy: frame-ancestors 'none'

这表示禁止任何页面嵌套当前页面。

总结

CSP 通过细粒度的控制策略限制网页加载和执行的资源,防止了恶意脚本和数据注入,从而大大减少了 XSS 攻击的风险。开发者可以通过设置和调整 CSP 策略来保护他们的应用免受各种攻击。

CSP 不能阻止浏览器插件的注入。浏览器插件通常有更高的权限,可以绕过 CSP 的限制。插件的代码运行在浏览器的不同上下文中,因此 CSP 对它们的行为没有直接影响。

 

标签:脚本,setTimeout,前端,任务,了解,深入,Promise,执行,CSP
From: https://www.cnblogs.com/skybreak/p/18409782

相关文章

  • 一个称职的嵌入式软件开发人员需要掌握了解的
    数据结构与算法,单片机原理,cortexM,A,R系列内核架构原理   编译原理   编程语言:asm,C/C++,java,python,C#,shell,bat,xml,json,perl,groovy(gradle使用的编写gradle脚本的),maven,kotlin,UML   linux基本操作:基本命令的使用,ubuntu安装配置,安......
  • 深入了解API接口功能应用
    电商API接口在现代电子商务中扮演着至关重要的角色,它们为开发者提供了一种强大的方式来获取和操作电商平台上的数据。以下是关于电商API接口的功能及应用的详细介绍。功能:商品信息获取:API接口可以提供商品的详细信息,包括名称、描述、价格、库存等,这对于商品管理和分析至关重......
  • 前端vue2 常用的函数
    1、在el-menu开启路由模式,default-active使用动态值等于当前路由,就需要用:default-active="$route.path" 2、阿里巴巴矢量图icfont的使用 ①将自己需要的图标下载到矢量库对应的项目文件中 ②更新对应的css代码,点击css代码链接,更新到本地去 ③使用<iclass="iconfont......
  • 苍穹外卖返回前端dishdto信息为null (已解决)-小白篇
    如图,半个小时的注解检查结果每次返回都是null,无法获取dishDto数据最终注意到dishcontroller中的注解少了@requestbody注解   @RequestBody是SpringMVC中的注解,用于将HTTP请求的请求体(body)中的JSON/XML格式的数据转换成Java对象。    在前后端分离的应用中,通......
  • 了解base64的一些隐写
    今天刷题发现base64原来还能隐写,隐写主要是靠base64后面补的等号。因为base64在加密的时候如果后面位数不足就会补=(00),而解码的时候如果后面有多余的就直接丢弃,这样也不会影响原文。那我们如果补00的时候补的不是00呢,那我们岂不是可以在这上面做文章,这样就能做到隐写了。解码的......
  • 带你了解Android Jetpack库中的依赖注入框架:Hilt
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点Hilt概述Hilt是Google推出的一种用于Android的依赖注入(DependencyInjection,DI)框架,构建于Dagger之上,旨在简化Android应用中的依赖注入过程。通过Hilt,你可以更轻松......
  • 快速搭建最简单的前端项目vue+View UI Plus
    1引言‌‌Vue是一套用于构建Web前端界面的渐进式JavaScript框架。‌‌它以其易学易用、性能出色、灵活多变而深受开发者喜爱,并且与其他前端框架(如‌React和‌Angular)相比,在国内市场上受到了广泛的认可和使用。点击进入官方网站。ViewUIPlus是ViewDesign设计体系中......
  • 后台查询数据渲染前端
    后台代码:@GetMapping("/getAll")//多层封装多条信息查询用listpublicResultgetAll(){Listlist=userService.getAdmin();returnResult.success(list);}publicListgetAdmin(){returnadminDao.selectAll();}params类@DatapublicclassParams{privateStr......
  • 前端算法(持续更新)
    1、最大的钻石1楼到n楼的每层电梯口都放着一个钻石,钻石大小不一。你从电梯1楼到n楼,每层楼电梯门都会打开一次,只能拿一次钻石,问怎样才能最大的钻石?解题思路:这是一个经典的动态规划问题,可以使用贪心算法来解决。以下是解决这个问题的思路:定义问题从1楼到n楼,每层楼电......
  • 前端常见算法题
    1、去除字符串中出现次数最少的字符,不改变原字符串的顺序实现删除字符串中出现次数最少的字符,若出现次数最少的字符有多个,则把出现次数最少的字符都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。“ababac”——“ababa”“aaabbbcceeff”——“aaa......