js是一门单线程语言,所以同一时间只能执行一个任务。为了防止主线程不阻塞,开发者提出了事件循环(Event Loop)。
每次执行栈执行的的代码都可以看做一个宏任务。
浏览器为了能够是js内部的宏任务和DOM任务有序执行。每次宏任务结束下次宏任务开始前都会进行一次页面重绘。
宏任务->页面重绘->宏任务
常见的宏任务包含:
script(整体代码)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)
当前任务执行结束后立即执行的任务。当前任务结束后,下一个任务执行前(渲染之前)
常见的微任务包含:
Promise.then
Object.observe
MutaionObserver
process.nextTick(Node.js 环境)
宏任务和微任务被放在了不同的队列中。
当前宏任务执行完成后会检查微任务队列中是否存在任务,有则执行。
宏任务的优先级高于微任务
console.log("script start")
setTimeout(()=>{
console.log("异步宏任务")
},0)
new Promise((resolve)=>{
console.log("异步微任务")
resolve()
}).then(()=>{
console.log("微任务1")
})
console.log("script end")
script start
异步微任务
script end
微任务1
异步宏任务
解析:
script start
、Promise
、script end
放入主线程执行栈、setTimeout
放入异步宏任务队列。Promise是立即执行函数,在其创建的时候就被执行了,只有在then()执行时才会被推入微任务队列
script start
执行完成后,立即执行new Promise
任务。resolve
执行成功后,将then
放入微任务队列,同时,继续下一个宏任务。script end
本身就在主线程上,在同步执行栈中,优先执行同步任务。then
任务,立即执行。setTimeOut
。事件循环是解决js单线程运行阻塞的一种机制。
new操作主要完成了以下4个步骤:
XSS:(跨域脚本攻击)
攻击原理:
不需要做登陆验证,通过合法的操作(例如在输入框输入脚本,url添加脚本参数),向你的页面注入可执行脚本,从而破坏页面正常结构,或插入广告等恶意内容。
攻击方式:
防御措施:
CSRF:跨站请求伪造
攻击原理:
防御措施:
作用域是存储和访问变量的一套规则,定义了变量的可访问性。常分为局部作用域、全局作用域、块级作用域。
编译过程一般分为三个步骤:词法分析、解析词法、代码生成。
通常会将代码解析成有意义的代码块,这些代码块叫做词法单元。
例如:
var a=2
解析后为:
var、a、=、2
将词法单元组成一个抽象语法树(AST)。
将抽象语法树转化成可执行的代码,并将变量存储到内存中。
作用域就是负责维护所有声明的变量和查询操作而存在的。
以var a = 2
为例
当浏览器请求某个文件时,会根据response header中的缓存字段,并且判断其是否缓存超时,如果未超时,则不发起请求,直接利用浏览器缓存的资源,状态码:200。
强缓存的header字段有2个:
expires:它是http1.0时的提出的。它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源。
cache-control:max-age=number:它是http1.1时提出的。主要利用max-age的值来判断是否超时,其值是一个相对值。资源第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则未命中。
cache-control
有以下几个常用值:
no-cache
:不使用本地缓存,需要使用协商缓存,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务器进行验证,未过期则不更新。no-store
:禁用浏览器缓存,用户的每次请求都将重新从服务器下载全新的资源。public
:可以被所有用户缓存,包含终端用户和CDN等中间代理服务器。private
:只能被终端用户的浏览器缓存,不允许代理服务器对其缓存。max-age
:缓存相对时间,与上一次资源变更时间相加,用于计算资源过期时间。cache-control的优先级高于expires
当强缓存未命中的时候,向服务端发送请求,根据响应头的信息,判端浏览器的缓存资源是否和服务器资源一致,如果一致,则仅返回一个请求头状态码304,如果不一致,则重新返回浏览器资源,同时修改请求头信息,状态码为200.
协商缓存是客户端与服务端公共约定的一套通讯标识,用于让服务端能清晰的判断请求资源是否可以缓存访问。协商缓存的字段是成对出现的,如果请求头不包含缓存字段,那么响应头也不会有。
常用的协商缓存字段有以下2对:
Last-Modified/If-Modified-Since
:这2者都是一个GMT格式的时间字符串。具体使用流程如下:
respone header
加上Last-Modified
字段,其表示资源在服务器上的最后修改时间。request header
上加上If-Modified-Since
字段,其表示上一次请求资源时返回的Last-Modified
的值。If-Modified-Since
和服务器资源的最后更新时间进行比较,如果未变化,则返回304 Not Modified
,浏览器直接利用缓存,如果缓存未命中,则重新加载服务端的资源,且修改respone header
中的Last-Modified
。*Etag/If-None-Match
:这两个值都是服务器生成的资源唯一标识,当资源变化时唯一标识也会变化。
判断流程与Last-Modified/If-Modified-Since
类似。
Etag
相较于Last-Modified
的优点:
Last-Modified
与ETag
可以一起使用,但必须遵循缓存优先级。
cache-control
>expries
>etag
>last-modified
需注意:
- F5刷新并不会修改
expires/cache-control
,但是会对last-modified/etag
进行验证。- ctrl+F5强制刷新,对
expires/cache-control
和last-modified/etag
都没有影响,会完全利用浏览器缓存。- 其他刷新操作均会进行缓存校验