ServiceWorker VI

ServiceWorker 导航预加载

导航预加载通过 NavigationPreloadManager 接口提供,并通过 ServiceWorkerRegistration.navigationPreload 属性暴露

对于使用 ServiceWorker 的页面,网页的网络请求会向 ServiceWorker 发送 fetch 事件直至返回响应,若此时 ServiceWorker 未启动,网页的网络请求会等待 ServiceWorker 激活后再进行处理;导航预加载允许网页的获取资源请求在 ServiceWorker 激活前提前开始下载,以避免阻碍页面的显示

启用导航预加载

NavigationPreloadManager 接口的 enable() 方法用于启用资源预加载管理

停用导航预加载

NavigationPreloadManager 接口的 disable() 方法用于停用资源预加载管理

管理导航预加载

NavigationPreloadManager 接口的 setHeaderValue() 方法用于设置导航预加载中发送的请求的请求头 Service-Worker-Navigation-Preload 的值

NavigationPreloadManager 接口的 getState() 方法用于获取导航预加载的状态

基本使用

启用导航预加载

1
2
3
4
5
self.addEventListener('activate', (e) => {
e.waitUntil(
self.registration.navigationPreload.enable()
)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
self.addEventListener('fetch', (e) => {
e.responseWith(
(async () => {
const cache = await self.caches.match(e.request)

if (cache != null) {
return cache
}

const preload = await e.preloadResponse

if (preload != null) {
return preload
}

return fetch(e.request)
})
)
})

链接

面试-工程

Git 常用指令

  • git init 创建一个空 git 代码库或初始化现有的 git 代码库
  • git clone 从远程克隆一个代码库到本地
  • git pull 从远程仓库或其他本地分支获取更新并与当前仓库分支合并
  • git push 将本地分支更新推送到远程仓库
  • git fetch 从远程仓库获取更新
  • git add 添加更新到暂存区
  • git commit 提交暂存区到仓库区

常见前端网络安全漏洞

  • XSS 攻击 - 跨站脚本攻击

攻击者向网站中注入恶意代码,使得其在浏览器中执行,并用于恶意目的如盗取客户端信息等

浏览器将恶意代码当成正常代码的一部分执行而导致

避免服务端拼接代码;充分转义将插入代码的内容;指定 CSP 策略,控制允许加载和执行的外部资源;敏感资源保护,如 Cookie 的 HttpOnly 策略、验证码等

  • CSRF 攻击 - 跨站请求伪造攻击

攻击者诱导用户进入第三方网站,随后第三方网站向被攻击网站发送跨站请求,利用用户保存的登录态执行恶意操作

Cookie 会在同源请求中自动携带并发送给服务器

进行同源检测,利用 origin 头和 referer 头;设置 Cookie 为 SameOrigin,阻止第三方页面使用该 Cookie;启用 Cookie 双重验证,将 Cookie 放入请求参数;使用 CSRF Token,请求参数中使用专属 token 验证身份

面试-JavaScript

宏任务与微任务

宏任务(普通脚本,setTimeout()setInterval(),I/O,UI 渲染)

微任务(PromiseMutationObserver

特殊任务 process.nextTick() 当前 event loop tick 将结束时且下一个 event loop tick 将开始时执行

特殊任务 setImmediate() 下一轮 event loop tick 的 macrotask 阶段将结束时执行

事件循环(Node)

  • 同步任务

  • 发出异步请求

  • 规划定时器生效的时间

  • 执行 process.nextTick() 的回调

  • timers - 处理 setTimeout()setInterval() 的回调函数

  • I/O callbacks - 剩余的回调函数(setTimeout()setInterval()setImmediate() 及关闭请求回调函数之外)

  • idle, prepare - 内部使用

  • poll - 轮询时间,等待还未返回的 I/O 事件

  • check - 执行 setImmediate() 的回调

  • close callbacks - 关闭请求的回调

继承模式

  • 原型链继承

    1
    2
    SubType.prototype = new SuperType()
    SubType.prototype.constructor = SubType
  • 构造函数继承

    1
    SuperType.call(this, superProp)
  • 组合式继承

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function SuperType(superProp){
    this.superProp = superProp
    }
    SuperType.prototype.printSuperProp = function(){
    console.log(this.superProp)
    }

    function SubType(superProp, subProp){
    SuperType.call(this, superProp)
    this.subProp = subProp
    }
    SubType.prototype = new SuperType()
    SubType.prototype.constructor = SubType
    SubType.prototype.printSubProp = function(){
    console.log(this.subProp)
    }
  • 寄生组合式继承

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function SuperType(superProp){
    this.superProp = superProp
    }
    SuperType.prototype.printSuperProp = function(){
    console.log(this.superProp)
    }

    function SubType(superProp, subProp){
    SuperType.call(this, superProp)
    this.subProp = subProp
    }
    SubType.prototype = Object.create(SuperType.prototype)
    SubType.prototype.constructor = SubType
    SubType.prototype.printSubProp = function(){
    console.log(this.subProp)
    }

Object 三种冻结方式

  • Object.preventExtensions() | Object.isExtensible() | 阻止添加属性,原型不可更改

  • Object.seal() | Object.isSealed() | 阻止添加属性,阻止移除属性,阻止配置属性(configurable 为 false),原型不可更改

  • Object.freeze() | Object.isFrozen() | 阻止添加属性,阻止移除属性,阻止修改属性值,阻止配置属性(writable、configurable 为 false),原型不可更改

面试-CSS

盒模型概念

页面中的一个元素在页面中占有的空间

包括:盒子中的元素内容(content)、内边距(padding)、边框(border)和外边距(margin)所占据的空间

  • 块状盒子
    • 盒子会占据单行
    • 宽度和高度指定有效
    • 内边距、边框和外边距会导致其他元素推离盒子
    • 若宽度未指定,默认盒子宽度会尽可能占据可用空间,通常为父元素宽度的100%
  • 行内盒子
    • 盒子不会占据单行
    • 宽度和高度指定无效
    • 上下内边距、边框和外边距会起效,但不会导致其他行内元素推离盒子
    • 左右内边距、边框和外边距会起效,且会导致其他行内元素推离盒子

面试-HTML

语义化标签作用

  • 优化 SEO,提升页面的搜索引擎的优先级
  • 便于其他设备解析,如屏幕阅读器等,方便残障人员的访问
  • 优化整体代码格式,增强语义化,便于代码的开发与维护
  • 便于用户阅读,特别是针对样式丢失的情形

面试-Vue

Vue diff 算法

  1. 首先比较新老节点是否为同一节点,若不是的话则删除该节点并创建新节点以进行替换
  2. 若为相同节点,则会对节点的子节点进行判断
  3. 先判断是否属于一方无子节点而一方有子节点的情况
  4. 若双方均有子节点,则判断如何对新老节点的子节点进行操作;若找到相同的子节点,则对子节点的子节点也递归进行比较

Vue3 相较于 Vue2 的区别

  • Vue3 的响应式基于 Proxy 实现;Vue2 的响应式基于 Object.defineProperty 实现

  • Vue3 更推荐使用 Composition API;Vue2 更推荐使用 Options API

  • Vue3 相较 Vue2 更利用 TypeScript 开发

  • Vue3 相对于 Vue2 更支持 TreeShaking

组件通信方式

  • props & emits 父=>子 & 子=>父

  • provide & inject 祖=>孙

  • ref|$refs 引用 & expose

  • 事件总线 EventBus & $on|$emit

  • $parent & $root

  • $attrs

<keep-alive> 理解

在组件切换的时候,保存一些组件的状态防止重复渲染 DOM

LRU 缓存策略 - 找出最久未使用的数据并置换新的数据
通常基于链表实现,将新数据插至链表头部,若命中已有数据则将老数据移至链表头部,链表满后则丢弃链表尾部的数据

此时组件会增加 deactivatedactivated 生命周期钩子,而替代 mountedunmounted 生命周期钩子

nextTick() 理解

作为 Vue 内部的异步队列的调用方法同时提供给开发者使用,核心是利用了如 PromiseMutationObserversetImmediate()setTimeout() 等原生 JavaScript 方法来模拟对应的微/宏任务的实现,本质是对 JavaScript 执行原理 EventLoop 的一种应用

通常在数据变化后执行的某个操作需要使用随数据变化而变化的 DOM 结构的时候或需在 created 生命周期内修改 DOM 结构时使用

MVVM 概念

Model - 数据模型,定义数据和业务逻辑

View - UI 视图,负责数据展示

ViewModel - 负责监听 Model 数据改变并控制视图更新,同时处理用户交互操作

面试-计算机网络

HTTP2 与 HTTP1 区别

  • HTTP2 是一个二进制协议

HTTP1.1 的报头必须是文本,数据体可以是文本或是二进制
HTTP2 的报头和数据体均为二进制,分别被称为头信息帧和数据帧

  • HTTP2 实现头信息压缩

HTTP2 中头信息使用 gzip 或 compress 压缩后再发送
HTTP2 中客户端和服务器同时维护一张头信息表,所有字段存储在表中并生成索引号,头信息不会重复多次发送,后续头信息利用索引号避免重复发送

  • HTTP2 支持多路复用

HTTP2 支持同时无序的发送多个请求或响应,从而避免队头堵塞的问题

  • HTTP2 使用数据流的概念

因为 HTTP2 的数据包不是按序发送的,同个连接内的数据包可能属于不同的请求;因此 HTTP2 中将每个请求或响应的数据包均作为数据流给出唯一的编号,每个数据包均需标记数据流 ID,以表示其所属的数据流 ID

  • HTTP2 支持服务器推送

HTTP2 允许服务器未经请求,主导向客户端发送资源,可以一定程度上减少延迟时间

HTTP3 与 HTTP2 区别

  • 流量控制、传输可靠性

  • 集成 TLS 加密功能

  • 多路复用 - 同一物理连接上可以有多个独立的逻辑数据流

  • 快速连接 - 基于 UDP,仅需 1~2 RTT 建立连接

TCP 与 UDP 区别

  • TCP 是面向连接;UDP 是面向无连接

TCP 发送数据前必须建立连接后发送数据
UDP 发送数据前不建立连接直接发送

  • TCP 是可靠传输,使用流量控制和拥塞控制;UDP 是不可靠传输,不支持流量控制和拥塞控制

TCP 连接通过给包编号并通过接收到数据后返回的 ACK 判断传输是否成功,从而确定是否重传数据;在出现拥塞时,会通过减小注入网络数据的速率和数量以缓解拥塞
UDP 不会进行检测包的发送成功与否,以恒定速率发送数据,不会根据网络状况调整发送速率

  • TCP 只能是一对一;UDP 可以一对一或一对多或多对一或多对多

TCP 连接只有两个端点,只能进行点对点的数据传输
UDP 支持单播、多播、广播功能

  • TCP 是面向字节流传输;UDP 是面向报文传输

TCP 连接在不保留报文边界情况下以字节流传输数据
UDP 连接在保留报文边界情况下以报文形式传输数据

  • TCP 首部最小 20 字节到 60 字节;UDP 首部为 8 字节

  • TCP 使用要求可靠连接的应用;UDP 适用于实时应用

常见 HTTP 状态码

  • 200 OK 服务器成功处理
  • 301 Moved Permanently 永久重定向
  • 302 Found 临时重定向资源
  • 304 Not Modified 使用客户端缓存
  • 403 Forbidden 服务器拒绝资源访问
  • 404 Not Found 服务器未找到资源或无原因的拒绝访问
  • 500 Internal Server Error 服务器执行出错

TCP/IP五层协议

  • 应用层 - 直接为应用进程提供服务 | HTTP HTTPS DNS FTP SMTP
  • 传输层 - 负责为主机的进程提供通信服务 | TCP UDP
  • 网络层 - 负责为主机提供通信服务 | IP寻址
  • 数据链路层 - 负责将数据封装为帧并在链路间传输 | MAC地址
  • 物理层 - 负责保证数据在物理介质上传输

TCP 三次握手及四次挥手

  • 客户端向服务端发送连接请求报文段

  • 服务端发送同意连接应答

  • 客户端向服务端发送一个确认报文

  • 客户端向服务端发送连接释放请求

  • 服务端不再接收客户端发的数据,仍旧可以发送数据给客户端

  • 服务端向客户端发送连接释放请求

  • 客户端向服务端发送确认应答

HTTPS 过程

  1. 客户端向服务器发起请求,请求中包含使用的协议版本号、生成的一个随机数、以及客户端支持的加密方法
  2. 服务器端接收到请求后,确认双方使用的加密方法、并给出服务器的证书、以及一个服务器生成的随机数
  3. 客户端确认服务器证书有效后,生成一个新的随机数,并使用数字证书中的公钥,加密这个随机数,然后发给服务器。并且还会提供一个前面所有内容的 hash 值,用来供服务器检验。
  4. 服务器使用自己的私钥,来解密客户端发送过来的随机数。并提供前面所有内容的 hash 值来供客户端检验。
  5. 客户端和服务器端根据约定的加密方法使用前面的三个随机数,生成对话秘钥,以后的对话过程都使用这个秘钥来加密信息。

SharedWorker

SharedWorker 是 HTML 标准定义的 Web API 的一部分,是一种特殊的 Worker,支持在多个上下文(例如 window、iframe 甚至 Worker)之间共享

同时,SharedWorker 的全局上下文 SharedWorkerGlobalScope 也与 Worker 不同

创建 SharedWorker

和 Worker 一样,通过调用 SharedWorker() 构造函数来创建

1
const worker = new SharedWorker('./worker.js')

SharedWorker() 构造函数支持传入一组可选的配置项,与 Worker() 构造函数相同
SharedWorker() 构造函数也支持直接传入一个字符串,同配置项的 name 参数;特别的,SharedWorker() 中的 name 参数作为唯一的一个标识符,在创建新的与之前的拥有相同 URL 的 SharedWorker 时有一定作用

SharedWorker 通过脚本文件 URL 和 name 参数确定是否为同一个 SharedWorker

SharedWorker 消息传递

与 Worker 不同,Client 端通过创建的 SharedWorker 实例上的 port 属性暴露的 MessagePort 接口实例,调用其上的 postMessage() 方法实现发送消息

Client 端通过监听 SharedWorker 实例上的 message 事件实现接收到消息

1
2
3
4
5
6
7
8
9
worker.port.start()

worker.port.postMessage('message from client')

worker.port.close()

worker.port.addEventListener('message', (e) => {
console.log('receive message in client: ', e.data)
})

SharedWorker 环境下接收消息,需要监听 connect 事件,从而获取到新的对应的 MessagePort 实例;监听 MessagePort 实例的 message 事件接收消息

SharedWorker 环境下接收消息,同样需要通过调用 MessagePort 实例的 postMessage() 方法实现发送消息

1
2
3
4
5
6
7
8
9
10
11
12
13
self.addEventListener('connect', (e) => {
const port = e.ports.at(0)

port.addEventListener('message', (e) => {
console.log('receive message in worker: ', e.data)
})

port.start()

port.postMessage('message from worker')

port.close()
})

通常,在 connect 事件回调函数内,会把接收到的 port 存储下来,以便之后使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const ports = []

self.addEventListener('connect', (e) => {
const port = e.ports.at(0)

port.addEventListener('message', handleReceiveMessage)

port.start()

ports.push(port)
})

function sendMessage() {
for (const port of ports) {
port.postMessage('message from worker')
}
}

卸载 SharedWorker

仅支持在 SharedWorker 环境内调用 close() 方法,来卸载当前 Worker

1
self.close()

SharedWorker 生命周期

SharedWorker 生命周期与 Client 端的生命周期独立,当任一页面创建 SharedWorker 时其生命周期开始,在没有页面使用 SharedWorker 时其生命周期结束

SharedWorker 全局环境

SharedWorker 全局环境通过 SharedWorkerGlobalScope 表示,该接口继承自 WorkerGlobalScope,它与 Worker 全局环境差别不大

示例

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
interface SharedWorker extends EventTarget, AbstractWorker {
constructor(scriptURL: string | URL, options?: string | WorkerOptions);
readonly port: MessagePort;
}

interface SharedWorkerGlobalScope extends WorkerGlobalScope {
readonly name: string;
close(): void;
onconnect: ((this: SharedWorkerGlobalScope, ev: MessageEvent) => any) | null;
}

interface WorkerOptions {
credentials?: RequestCredentials
name?: string
type?: WorkerType
}

type WorkerType = 'classic' | 'module'

链接

Worker

Web Worker 是 HTML 标准定义的 Web API 的一部分,可以在后台运行一个耗时的任务,避免因长期执行 JS 任务而阻塞用户界面渲染与交互

Web Worker 可以被 Window 环境创建,也可以被其他的 Worker 创建

Web Worker 是独立于主线程的一个线程,具有独立的作用域,其中运行的任务不会阻塞主线程

Web Worker 中的全局作用域 DedicatedWorkerGlobalScope 与 Window 的全局作用域不同,Window 环境中部分 API 在 Worker 环境中不可用或受到一定的限制

Web Worker 线程与主线程之间的通信通过 message 机制实现,传递的数据通过结构化拷贝算法传递,因此通常不存在处理线程安全的需要

创建 Worker

通过调用 Worker() 构造函数,传入 Worker 脚本的 URL,来创建一个 Worker

1
const worker = new Worker('./worker.js')

Worker 脚本需要与 Client 同域

Worker() 构造函数支持传入一组可选的配置项
type 参数指定脚本的类型,值可以是 classicmodule,默认值是 classic
name 参数指定 Worker 的名称,在 debug 时候有一定作用,在 Worker 内可以通过 name 只读属性访问
credentials 参数指定 Worker 的 credentials 选项,允许的值可以是 omitsame-origininclude
若传入的 URL 解析失败,会抛出一个 SyntaxError 错误
若接收到的脚本文件并非 JavaScript 格式,会抛出 NetworkError 错误
若当前文档环境不支持创建 Worker,如未遵守同源策略,会抛出 SecurityError 错误

Worker 消息传递

无论是 Worker 端还是 Client 端,通过调用 postMessage() 方法实现发送消息,通过监听 message 事件实现接收消息

Client 发送消息

1
worker.postMessage('message from client')

Client 接收消息

1
2
3
worker.addEventListener('message', (e) => {
console.log('receive message in client: ', e.data)
})

Worker 发送消息

1
self.postMessage('message from worker')

Worker 发送消息

1
2
3
self.addEventListener('message', (e) => {
console.log('receive message in worker: ', e.data)
})

此外,可以选择传入一组数组或包含 transfer 参数的配置项,定义需要转移所有权的对象

所有权被转移后,对应对象在原环境内不再可用,而是仅在新环境内可用

普通消息

当然,传递的消息可以不仅仅是 string 类型,可以是其他任何可以被结构化拷贝算法执行的数据,包括:

  • number
  • string
  • boolean
  • null
  • undefined
  • bigint
  • 普通 object
  • Array
  • RegExp
  • Date
  • Error
  • Set
  • Map
  • Blob
  • ArrayBuffer
  • TypedArray
  • 等等

结构化拷贝算法,严格来说,与 JSON.stringfy()JSON.parse() 行为上不同。在结构化拷贝算法中,试图复制 Function 参数会抛出异常;但结构化拷贝算法支持复制包含循环对象的对象

可转移对象

可以转移的对象可以是:

  • ArrayBuffer
  • MessagePort
  • ReadableStream
  • WritableStream
  • TransformStream
  • WebTransportReceiveStream
  • AudioData
  • ImageBitmap
  • VideoFrame
  • OffscreenCanvas
  • RTCDataChannel

可共享对象

SharedArrayBuffer 可以用于多个线程之间的共享数据,并利用 Atomics 实现线程同步与线程锁功能。

启用该 API 需要 secure context,并且需要 cross-origin isolate,可以通过检测 isSecureContext 全局变量和 crossOriginIsolated 全局变量来确定是否可以使用 SharedArrayBuffer

卸载 Worker

通过调用 worker 实例的 terminate() 方法,来卸载一个 Worker

1
worker.terminate()

或者调用 Worker 环境中的 close() 方法,来卸载当前的 Worker

1
self.close()

卸载是立即执行的,不会等待 worker 内部任务的完成

Worker 全局环境

Worker 全局环境通过 DedicatedWorkerGlobalScope 表示,该接口继承自 WorkerGlobalScope

Worker 全局环境的 messageerror 事件会在传递的消息无法解析时触发,可用用于监听发送失败的消息(Worker 对象上同样存在)

Worker 全局环境的 importScripts() 方法可以导入一组同源的脚本文件,并在 Worker 全局环境下执行

示例

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

interface Worker extends EventTarget, AbstractWorker {
constructor(scriptURL: string | URL, options?: WorkerOptions)
postMessage(message: any, transfer: Transferable[]): void
postMessage(message: any, options?: StructuredSerializeOptions): void
terminate(): void
}

interface DedicatedWorkerGlobalScope extends WorkerGlobalScope {
readonly name: string
close(): void
onmessage: ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null
onmessageerror: ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null
postMessage(message: any, transfer: Transferable[]): void
postMessage(message: any, options?: StructuredSerializeOptions): void
}

interface StructuredSerializeOptions {
transfer?: Transferable[]
}

interface WorkerOptions {
credentials?: RequestCredentials
name?: string
type?: WorkerType
}

type WorkerType = 'classic' | 'module'

链接

ServiceWorker II

ServiceWorker 全局上下文

ServiceWorkerGlobalScope 接口代表 ServiceWorker 的全局上下文,在 ServiceWorker 内通过 self 全局变量或者 globalThis 全局变量访问(该接口继承自 WorkerGlobalScope)。

ServiceWorkerGlobalScope

以下代表在 ServiceWorkerGlobalScope 接口本身的属性、方法和事件

  • ServiceWorkerGlobalScope 接口的 clients 属性代表一个 Clients 实例,可用于获取 Client (可执行上下文)实例。

  • ServiceWorkerGlobalScope 接口的 registration 属性代表一个 ServiceWorkerRegistration 实例,即当前 ServiceWorker 注册的引用。

  • ServiceWorkerGlobalScope 接口的 serviceWorker 属性代表一个 ServiceWorker 实例,即当前 ServiceWorker 实例的引用。

  • ServiceWorkerGlobalScope 接口的 skipWaiting 方法强制当前 ServiceWorker 从等待状态变成激活状态,返回一个该 ServiceWorker 激活后完成的 Promise。其在 install 事件的回调中调用才具有实际意义。

WorkerGlobalScope

以下代表继承自 WorkerGlobalScope 接口的属性、方法和事件

  • WorkerGlobalScope 接口的 location 属性代表一个 WorkerLocation 实例,是 Location 的字集。

  • WorkerGlobalScope 接口的 navigator 属性代表一个 WorkerNavigator 实例,是 Navigator 的字集。

  • WorkerGlobalScope 接口的 self 属性代表 WorkerGlobalScope 接口本身。

  • WorkerGlobalScope 接口的 importScripts 方法同步导入一组脚本文件并执行,接受一组参数,代表脚本文件的 URL,其可以为绝对路径或相对路径(相对文档路径)。

  • WorkerGlobalScope 接口的 error 事件在 ServiceWorker 内发生脚本错误时触发,返回一个 Event 实例。

  • WorkerGlobalScope 接口的 languagechange 事件在用户的首选语言更改时触发,返回一个 Event 实例。

  • WorkerGlobalScope 接口的 online 事件在浏览器获得网络访问权限并且 navigator.onLine 值切换到 true 时触发,返回一个 Event 实例。

  • WorkerGlobalScope 接口的 offline 事件在浏览器获得网络访问权限并且 navigator.onLine 值切换到 false 时触发,返回一个 Event 实例。

  • WorkerGlobalScope 接口的 rejectionhandled 事件在 ServiceWorker 内处理的 Promise 拒绝事件时触发,返回一个 Event 实例。

  • WorkerGlobalScope 接口的 unhandledrejection 事件在 ServiceWorker 内未处理的 Promise 拒绝事件时触发,返回一个 Event 实例。

以下代表暴露在全局的属性、方法和事件

1
2
3
4
5
6
7
8
self.fonts
self.caches
self.crossOriginIsolated
self.crypto
self.indexedDB
self.isSecureContext
self.origin
self.performance
1
2
3
4
5
6
7
8
9
10
11
self.atob()
self.btoa()
self.clearInterval()
self.clearTimeout()
self.createImageBitmap()
self.fetch()
self.queueMicrotask()
self.reportError()
self.setInterval()
self.setTimeout()
self.structuredClone()

示例

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
interface ServiceWorkerGlobalScope extends WorkerGlobalScope {
readonly clients: Clients;
readonly registration: ServiceWorkerRegistration;
readonly serviceWorker: ServiceWorker;
onactivate: ((this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any) | null;
onfetch: ((this: ServiceWorkerGlobalScope, ev: FetchEvent) => any) | null;
oninstall: ((this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any) | null;
onmessage: ((this: ServiceWorkerGlobalScope, ev: ExtendableMessageEvent) => any) | null;
onmessageerror: ((this: ServiceWorkerGlobalScope, ev: MessageEvent) => any) | null;
onnotificationclick: ((this: ServiceWorkerGlobalScope, ev: NotificationEvent) => any) | null;
onnotificationclose: ((this: ServiceWorkerGlobalScope, ev: NotificationEvent) => any) | null;
onpush: ((this: ServiceWorkerGlobalScope, ev: PushEvent) => any) | null;
onpushsubscriptionchange: ((this: ServiceWorkerGlobalScope, ev: Event) => any) | null;
skipWaiting(): Promise<void>;
}

interface WorkerGlobalScope extends EventTarget, FontFaceSource, WindowOrWorkerGlobalScope {
readonly location: WorkerLocation;
readonly navigator: WorkerNavigator;
readonly self: WorkerGlobalScope & typeof globalThis;
onerror: ((this: WorkerGlobalScope, ev: ErrorEvent) => any) | null;
onlanguagechange: ((this: WorkerGlobalScope, ev: Event) => any) | null;
onoffline: ((this: WorkerGlobalScope, ev: Event) => any) | null;
ononline: ((this: WorkerGlobalScope, ev: Event) => any) | null;
onrejectionhandled: ((this: WorkerGlobalScope, ev: PromiseRejectionEvent) => any) | null;
onunhandledrejection: ((this: WorkerGlobalScope, ev: PromiseRejectionEvent) => any) | null;
importScripts(...urls: (string | URL)[]): void;
}

interface WindowOrWorkerGlobalScope {
readonly caches: CacheStorage;
readonly crossOriginIsolated: boolean;
readonly crypto: Crypto;
readonly fonts: FontFaceSet;
readonly indexedDB: IDBFactory;
readonly isSecureContext: boolean;
readonly origin: string;
readonly performance: Performance;
atob(data: string): string;
btoa(data: string): string;
clearInterval(id: number | undefined): void;
clearTimeout(id: number | undefined): void;
createImageBitmap(image: ImageBitmapSource, options?: ImageBitmapOptions): Promise<ImageBitmap>;
createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
queueMicrotask(callback: VoidFunction): void;
reportError(e: any): void;
setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
structuredClone<T = any>(value: T, options?: StructuredSerializeOptions): T;
}

链接


:D 一言句子获取中...