Picture-in-Picture API

Picture-in-Picture API 允许某个特定的视频元素管理画中画模式

启用画中画模式

通过调用 HTMLVideoElement 接口上的 requestPictureInPicture() 方法以启用画中画模式

方法返回一个 Promise 的 PictureInPictureWindow

方法可能抛出 SecurityError 异常,如当前特性被 Permission Policy 拒绝

1
element.requestPictureInPicture()

停止画中画模式

通过调用 Document 接口上的 exitPictureInPicture() 方法以停止画中画模式

方法返回一个 Promise

1
document.exitPictureInPicture()

画中画模式信息

HTMLVideoElement 接口上的 disablePictureInPicture 属性反映了当前视频元素的画中画模式是否可用,返回 boolean

Document 接口上的 pictureInPictureEnabled 只读属性反映了当前文档的画中画模式是否可用,返回 boolean

Document 接口或 ShadowRoot 接口上的 pictureInPictureElement 只读属性反映了当前处于画中画模式的元素,返回 Element 值或 null

HTMLVideoElement 接口上的 enterpictureinpicture 事件在当前元素成功启用画中画模式时触发,返回一个 PictureInPictureEvent 事件

HTMLVideoElement 接口上的 leavepictureinpicture 事件在当前元素成功停止画中画模式时触发,返回一个 PictureInPictureEvent 事件

PictureInPictureEvent 事件继承自 Event 事件,其唯一额外 pictureInPictureWindow 只读属性代表当前事件相关的 PictureInPictureWindow 实例

PictureInPictureWindow 接口反映了当前的画中画模式窗口,其 width 只读属性和 height 只读属性反映了窗口的宽高,其 resize 事件在窗口尺寸改变时触发并返回一个 PictureInPictureEvent 事件

权限策略

该 API 调用受到 picture-in-picture 权限策略的控制,可以通过 Permissions-Policy 响应头指定,或通过 <iframe> 标签的 allow 属性指定

默认值是 *,即允许任意源的浏览上下文使用该 API

类型

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
interface Document {
readonly pictureInPictureElement: Element | null
readonly pictureInPictureEnabled: boolean
exitPictureInPicture(): Promise<void>
}

interface ShadowRoot {
readonly pictureInPictureElement: Element | null
}

interface HTMLVideoElement {
disablePictureInPicture: boolean
requestPictureInPicture(): Promise<PictureInPictureWindow>
onenterpictureinpicture: ((this: HTMLVideoElement, ev: PictureInPictureEvent) => any) | null
onleavepictureinpicture: ((this: HTMLVideoElement, ev: PictureInPictureEvent) => any) | null
}

interface PictureInPictureEvent extends Event {
readonly pictureInPictureWindow: PictureInPictureWindow
}

interface PictureInPictureWindow extends EventTarget {
readonly width: number
readonly height: number
onresize: ((this: PictureInPictureWindow, ev: PictureInPictureEvent) => any) | null
}

链接

Fullscreen API

Fullscreen API 允许某个特定的元素管理全屏模式

启用全屏模式

通过调用 Element 接口上的 requestFullscreen() 方法以启用全屏模式

方法传入一个可选的配置项,其唯一 navigationUI 可选参数控制是否展示 navigation UI,值为 "auto" "show" "hide" 之一,默认值为 "auto"

方法返回一个 Promise

方法可能抛出 TypeError 异常,如当前文档并非处于活跃状态、当前元素未处于文档中、当前元素不允许使用全屏模式、当前元素是一个激活的 popover 元素、当前元素是 <dialog> 元素、当前元素不是 HTML SVG MathML 元素等等

1
element.requestFullscreen()

停止全屏模式

通过调用 Document 接口上的 exitFullscreen() 方法以停止全屏模式

方法返回一个 Promise

1
document.exitFullscreen()

全屏模式信息

Document 接口上的 fullscreenEnabled 属性反映了全屏模式是否可用,返回 boolean

Document 接口或 ShadowRoot 接口上的 fullscreenElement 属性反映了当前处于全屏模式的元素,返回 Element 值或 null

Document 接口或 Element 接口上的 fullscreenchange 事件在文档或元素的全屏状态改变时触发,返回一个 Event 事件

Document 接口或 Element 接口上的 fullscreenerror 事件在文档或元素的全屏状态改变失败时触发,返回一个 Event 事件

通常,监听 Web 程序内的全屏状态改变,通过监听 Document 接口上的即可,文档内元素的相应事件会冒泡至文档

权限策略

该 API 调用受到 fullscreen 权限策略的控制,可以通过 Permissions-Policy 响应头指定,或通过 <iframe> 标签的 allow 属性指定

默认为 self,即允许在当前上下文或内嵌的其他同源上下文中使用

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
interface Document {
readonly fullscreenElement: Element | null
readonly fullscreenEnabled: boolean
exitFullscreen(): Promise<void>
onfullscreenchange: ((this: Document, ev: Event) => any) | null
onfullscreenerror: ((this: Document, ev: Event) => any) | null
}

interface ShadowRoot {
readonly fullscreenElement: Element | null
}

interface Element {
requestFullscreen(options?: FullscreenOptions): Promise<void>
onfullscreenchange: ((this: Element, ev: Event) => any) | null
onfullscreenerror: ((this: Element, ev: Event) => any) | null
}

interface FullscreenOptions {
navigationUI?: FullscreenNavigationUI
}

type FullscreenNavigationUI = 'auto' | 'hide' | 'show'

链接

Keyboard Lock API

Keyboard Lock API 允许控制键盘的输入形式,捕获键盘的输入从而进行自定义的处理(特别是针对一些特殊按键)

通过 navigator.keyboard 暴露的 Keyboard 接口实例使用

该 API 的使用要求有用户交互的发生

启用键盘锁定

使用 Keyboard 接口的 lock() 方法启用键盘锁定

方法可以传递一个可选的 keyCodes 字符串数组参数,代表要锁定的键值码;不传递则代表锁定所有的按键

方法返回一个 Promise

方法可能抛出 AbortError,若在该方法完成前又重新调用了该方法

方法可能抛出 InvalidAccessError,若任一 keyCodes 中的项非法

方法可能抛出 InvalidStateError,若方法未在活跃浏览器上下文中调用

1
2
navigator.keyboard.lock()
navigator.keyboard.lock(['KeyW', 'KeyA', 'KeyS', 'KeyD'])

若调用多次调用 lock() 方法且中途未调用 unlock() 方法,则只有最后一次指定的 keyCodes 有效

停止键盘锁定

使用 Keyboard 接口的 unlock() 方法停止键盘锁定

1
navigator.keyboard.unlock()

类型

1
2
3
4
5
6
7
8
interface Keyboard extends EventTarget {
lock(keyCodes?: string[]): Promise<void>
unlock(): void
}

interface Navigator {
readonly keyboard: Keyboard
}

链接

Pointer Lock API

Pointer Lock API 允许控制鼠标的输入形式,将鼠标的移动从光标位置移动转换为自定义的形式(同时隐藏光标)

指针锁定与鼠标捕获比较类似,但其是持久的,即不会自动释放鼠标;并且其不受浏览器边界的限制;最大特点是,其会隐藏光标

启用指针锁定

通过调用对应 Element 接口上的 requestPointerLock() 方法以启用指针锁定

方法默认无参数,新提案支持传入一组配置项,唯一参数 unadjustedMovement 指定是否启用操作系统级别的鼠标位置适配,目前为部分浏览器支持

方法默认无返回值,但新提案支持返回 Promise,目前为部分浏览器支持

方法调用要求存在用户交互且为活跃文档,并且不允许连续调用该方法,并且 <iframe> 标签中的调用需要设置允许 allow-pointer-lock 沙箱策略并且除 该<iframe> 标签之外的其他 <iframe> 标签必须未处于指针调用状态,否则调用会失败

1
el.requestPointerLock()

停止指针锁定

通过调用 Document 接口上的 exitPointerLock() 方法以停止指针锁定

1
document.exitPointerLock()

指针锁定信息

Document 接口或 ShadowRoot 接口的 pointerLockElement 属性返回当前启用指针锁定的元素,若不存在则返回 null

Document 接口的 pointerlockchange 事件在指针锁定状态改变时触发,返回一个 Event 事件

Document 接口的 pointerlockerror 事件在指针锁定状态改变失败时触发,返回一个 Event 事件’

MouseEvent 接口的 movementX 属性与 movementY 属性仅在 mousemove 事件中可用,反映了前后两个 mousemove 事件的鼠标移动的坐标

沙箱策略

该 API 在 <iframe> 标签中的调用受到 allow-pointer-lock 沙箱策略的控制,需要将 sandbox 的属性指定为允许

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
interface Document {
exitPointerLock(): void
onpointerlockchange: ((this: Document, ev: Event) => any) | null
onpointerlockerror: ((this: Document, ev: Event) => any) | null
}

interface DocumentOrShadowRoot {
readonly pointerLockElement: Element | null
}

interface Element {
requestPointerLock(): void
}

interface MouseEvent {
readonly movementX: number
readonly movementY: number
}

链接

Screen Wake Lock API

Screen Wake Lock API 允许控制设备的屏幕变暗、休眠或锁定的策略

通过 navigator.wakeLock 暴露的 WakeLock 接口实例使用

启用屏幕管理策略

通过 WakeLock 接口的 request() 方法来请求启用屏幕管理策略

方法传入一个可选的 type 字符串参数,唯一允许值为 'screen'

方法返回一个 Promise 的 WakeLockSentinel 实例

方法可能抛出一个 NotAllowedError 异常,例如被 Permissions Policy 拒绝、当前网页未处于活跃状态、当前网页处于隐藏状态或用户代理无法获取到系统的屏幕管理策略

1
const sentinel = await navigator.wakeLock.request()

释放屏幕管理策略

通过 WakeLockSentinel 接口的 release() 方法来手动关闭屏幕管理策略

方法返回一个 Promise

1
sentinel.release()

同时,操作系统可能会在网页失去焦点或隐藏时自动关闭屏幕管理策略

屏幕管理策略信息

WakeLockSentinel 接口的 released 属性返回一个 boolean,表示当前 WakeLockSentinel 是否已被释放

WakeLockSentinel 接口的 type 属性返回一个 string,表示当前 WakeLockSentinel 的类型

WakeLockSentinel 接口的 release 事件,在 WakeLockSentinel 被释放时触发,返回一个 Event 事件

权限策略

该 API 调用受到 screen-wake-lock 权限策略的控制,可以通过 Permissions-Policy 响应头指定,或通过 <iframe> 标签的 allow 属性指定

默认为 self,即允许在当前上下文或内嵌的其他同源上下文中使用

类型

1
2
3
4
5
6
7
8
9
10
11
12
interface WakeLock {
request(type?: WakeLockType): Promise<WakeLockSentinel>
}

interface WakeLockSentinel extends EventTarget {
onrelease: ((this: WakeLockSentinel, ev: Event) => any) | null
readonly released: boolean
readonly type: WakeLockType
release(): Promise<void>
}

type WakeLockType = 'screen'

链接

Battery Status API

Battery Status API 提供了访问设备电源信息和监听电源信息变化的功能,可以用于动态根据用户设备的电源情况调整一些功能的策略

获取电源管理实例

使用 Navigator 接口的 getBattery() 方法获取到电源管理实例,方法返回一个 Promise 的 BatteryManager 实例

1
const batteryManager = await navigator.getBattery()

获取设备电源信息

BatteryManager 接口提供了访问设备电源信息的属性

BatteryManager 接口的 charging 属性返回一个 boolean,表示当前设备是否处于充电状态

BatteryManager 接口的 chargingTime 属性返回一个 number,表示当前设备充电完成所需的充电时间,若设备已充满或无法获取电源信息则返回 0,若设备未处于充电状态则返回 +Infinity

BatteryManager 接口的 dischargingTime 属性返回一个 number,表示当前设备至完全耗尽电量的时间,若设备处于充电状态或无法获取电源信息则返回 +Infinity

BatteryManager 接口的 level 属性返回一个范围从 0.01.0 之间的 number,表示当前设备电源的电量百分比,若无法获取电源信息则返回 1.0

1
2
3
4
batteryManager.charging
batteryManager.chargingTime
batteryManager.dischargingTime
batteryManager.level

监听设备电源信息更新

BatteryManager 接口提供了监听设备电源信息变化的事件

BatteryManager 接口的 chargingchange 事件在电源充电状态改变时触发,即 charging 属性改变时触发

BatteryManager 接口的 chargingtimechange 事件在电源充电完成时间改变时触发,即 chargingTime 属性改变时触发

BatteryManager 接口的 dischargingtimechange 事件在电源电量耗尽时间改变时触发,即 dischargingTime 属性改变时触发

BatteryManager 接口的 levelchange 事件在电源电量改变时触发,即 level 属性改变时触发

1
2
3
4
5
6
7
8
9
10
11
12
batteryManager.addEventListener('chargingchange', () => {
console.log(batteryManager.charging)
})
batteryManager.addEventListener('chargingtimechange', () => {
console.log(batteryManager.chargingTime)
})
batteryManager.addEventListener('dischargingtimechange', () => {
console.log(batteryManager.dischargingTime)
})
batteryManager.addEventListener('levelchange', () => {
console.log(batteryManager.level)
})

权限策略

该 API 受 battery 权限策略的限制(无论是通过 Permissions-Policy 响应头指定抑或是通过 iframe 元素的 allow 属性指定)

默认为 self,即允许在当前上下文或内嵌的其他同源上下文中使用

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface Navigator {
getBattery: () => Promise<BatteryManager>
}

interface BatteryManager extends EventTarget {
readonly charging: boolean
readonly chargingTime: number
readonly dischargingTime: number
readonly level: number
onchargingchange: ((this: BatteryManager, ev: Event) => any) | null
onchargingtimechange: ((this: BatteryManager, ev: Event) => any) | null
ondischargingtimechange: ((this: BatteryManager, ev: Event) => any) | null
onlevelchange: ((this: BatteryManager, ev: Event) => any) | null
}

链接

Web Storage API

Web Storage API 可用于保存键值对形式的数据,包括 localStorage 和 sessionStorage 两种,键值对均要求为字符串(非字符串类型数据会隐式转换为字符串)

sessionStorage 会话存储的数据仅在当前会话中有效,若关闭标签页或浏览器则会失效

localStorage 本地存储的数据长期有效

Web Storage API 同样受同源策略限制,不同源的 Storage 无法共享

Storage 的获取

通过 window.sessionStorage 访问会话存储对应的 Storage 实例

通过 window.localStorage 访问本地存储对应的 Storage 实例

Storage 的操作

Storage 接口提供了一些对会话存储或本地存储的操作方法

读取键值对

Storage 接口的 getItem() 方法用于获取指定键名对应的键值,若数据不存在则返回 null

1
window.localStorage.getItem('k')

设置键值对

Storage 接口的 setItem() 方法用于设置键值对

1
window.localStorage.setItem('k', 'v')

清除键值对

Storage 接口的 removeItem() 方法用于移除指定键名对应的键值

1
window.localStorage.removeItem('k')

清空存储

Storage 接口的 clear() 方法用于清除整个存储

1
window.localStorage.clear()

其他

Storage 接口的 length 属性返回存储的长度

Storage 接口支持直接使用键名索引来获取或设置对应的键值,支持直接使用 delete 关键字移除对应的键值

Storage 接口的 key() 方法用于获取指定索引的值,索引的顺序是由浏览器决定的,因此该顺序是不可靠的,若数据不存在则返回 null

1
2
3
4
5
6
7
8
window.localStorage.length
window.localStorage.k
window.localStorage['k']
window.localStorage.k = 'v'
window.localStorage['k'] = 'v'
delete window.localStorage.k
delete window.localStorage['k']
window.localStorage.key(0)

存储更改

会话存储或本地存储的更改会在与之同域的会话中触发全局 Windowstorage 事件,并返回一个 StorageEvent 事件

StorageEvent 事件的 storageArea 属性返回存储变化的 Storage 实例

StorageEvent 事件的 url 属性返回存储变化的文档的 URL

StorageEvent 事件的 key 属性返回存储变化的键名

StorageEvent 事件的 oldValue 属性返回存储变化的原键值或 null

StorageEvent 事件的 newValue 属性返回存储变化的现键值或 null

1
2
3
4
5
6
7
window.addEventListener('storage', (e) => {
console.log(e.key)
console.log(e.oldValue)
console.log(e.newValue)
console.log(e.url)
console.log(e.storageArea)
})

类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
interface Window {
readonly localStorage: Storage
readonly sessionStorage: Storage
onstorage: ((this: WindowEventHandlers, ev: StorageEvent) => any) | null
}

interface Storage {
readonly length: number
clear(): void
getItem(key: string): string | null
key(index: number): string | null
removeItem(key: string): void
setItem(key: string, value: string): void
[name: string]: any
}

interface StorageEvent extends Event {
readonly key: string | null
readonly newValue: string | null
readonly oldValue: string | null
readonly storageArea: Storage | null
readonly url: string
initStorageEvent(type: string, bubbles?: boolean, cancelable?: boolean, key?: string | null, oldValue?: string | null, newValue?: string | null, url?: string | URL, storageArea?: Storage | null): void
}

链接

Cookie API

Cookie 是一小段保存在用户端的信息,用于改善用户的网络浏览体验,通常包括用户的选项或识别信息,用户可以选择网站使用 Cookie 的方式

可用使用 navigator.cookieEnabled 判断页面是否允许使用 Cookie

可以通过 Set-Cookie 响应头设置 Cookie 或使用 JS 脚本 document.cookie 设置 Cookie

1
2
HTTP/2.0 200 OK
Set-Cookie: cookie_a=a
1
document.cookie = 'cookie_b=b';

执行请求时可以通过 Cookie 请求头自动带上 Cookie

JS 脚本中可以通过 document.cookie 读取 Cookie

1
const cookies = document.cookie;
  • Expires 属性

    指定 Cookie 在给定时间后失效

  • Max-Age 属性

    指定 Cookie 在超出给定时长后失效

  • Secure 属性

    指定 Cookie 仅在 Secure Context 下才发送;并且非 Secure Context 下无法设置该属性

  • HttpOnly 属性

    指定 Cookie 无法通过 document.cookie 读取和修改

    常用于防御 XSS 攻击

  • Domain 属性

    指定 Cookie 可用的域名(及子域名),默认会包含当前的域名

  • Path 属性

    指定 Cookie 可用的路径(及子路径)

  • SameSite 属性

    指定 Cookie 是否在跨域请求中发送

    常用于防御 CSRF 攻击

    Strict 值指定仅在同域请求中发送

    Lax 值允许在用户导航至 Cookie 的域名时发送,该值是默认的行为

    None 值指定允许在跨域请求中发送,但需同时指定 Secure 属性

1
Set-Cookie: cookie_b=b; Expires=Thu, 31 Oct 2021 07:28:00 GMT; Secure; HttpOnly; Domain=example.com; Path=/; SameSite=Strict
  • __Host- 前缀

    指定对应的 Cookie 需指定 Secure 属性(即需要在 Secure Context 发送),不得指定 Domain 属性,Path 属性需指定为 /

  • __Secure- 前缀

    指定对应的 Cookie 需指定 Secure 属性(即需要在 Secure Context 发送)

链接

Geolocation API

Geolocation API 提供了访问用户地理位置的方法

通过 navigator.geolocation 暴露的 Geolocation 接口实例访问

使用 API 需要向用户请求授权并获得允许,并且仅在 Secure Context 环境下启用

获取地理位置

使用 Geolocation 接口的 getCurrentPosition() 方法获取地理位置

方法需要传入一个在获取地理位置成功时调用的回调函数,该回调函数会被传递一个 GeolocationPosition 参数

方法可以传入一个在获取地理位置失败时调用的回调函数,该回调函数会被传递一个 GeolocationPositionError 参数

方法同样可以传入一个可选的配置项:

maximumAge 可选选项接收一个正数值,指定使用缓存的地理位置的允许的最长的期限,默认为 0

timeout 可选选项接收一个正数值,指定获取地理位置等待的超时时间,默认为 Infinity

enableHighAccuracy 可选选项接收一个布尔值,指定是否尝试获取最精确的可能值,默认值 false

权限策略

该 API 调用受到 geolocation 权限策略的控制,可以通过 Permissions-Policy 响应头指定,或通过 <iframe> 标签的 allow 属性指定

默认值是 *,即允许任意源的浏览上下文使用该 API

权限 API

该 API 调用需要获得用户 geolocation 权限的允许,可以调用 Permission.query() 方法检查用户是否已授予了该权限

1
2
3
4
5
6
7
8
9
10
11
12
13
navigator.geolocation.getCurrentPosition(
(position) => {
// todo something with the position data
},
(error) => {
// todo something when getting position failed
},
{
maximumAge: 0,
timeout: Infinity,
enableHighAccuracy: false,
}
)

监听地理位置

使用 Geolocation 接口的 watchPosition() 方法注册监听地理位置的更新

方法的参数类似于 getCurrentPosition() 方法

方法返回一个数字,代表注册回调的 ID,可用于 clearWatch() 方法取消监听

使用 Geolocation 接口的 clearWatch() 方法取消注册监听地理位置的更新

地理位置信息

GeolocationPosition 接口用于表示一组地址位置信息记录

coords 只读属性代表一个 GeolocationCoordinates 实例,表示地址位置信息的具体内容

timestamp 只读属性返回一个时间戳,代表获取地址位置信息的时间点

GeolocationCoordinates 接口用于表示一个地址位置信息详情

latitude 只读属性代表纬度

longitude 只读属性代表经度

accuracy 只读属性代表经纬度精度

altitude 只读属性代表海平面高度,设备不支持时返回 null

altitudeAccuracy 只读属性代表海平面高度精度,设备不支持时返回 null

heading 只读属性代表设备方向,设备不支持时返回 null

speed 只读属性代表设备移动速度,设备不支持时返回 null

异常处理

GeolocationPositionError 接口表示获取地理位置失败的异常

code 只读属性代表错误状态码,可能为常量枚举 PERMISSION_DENIEDPOSITION_UNAVAILABLETIMEOUT 之一,常量枚举可以通过 GeolocationPositionError 本身或其实例访问

message 只读属性代表错误信息,通常是用于调试目的而非直接向用户展示

权限策略

该 API 调用受到 geolocation 权限策略的控制,可以通过 Permissions-Policy 响应头指定,或通过 <iframe> 标签的 allow 属性指定

默认为 self,即允许在当前上下文或内嵌的其他同源上下文中使用

权限 API

该 API 调用需要用户授予 geolocation 权限,可以调用 Permission.query() 方法检查用户是否已授予了该权限

类型

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
interface Navigator {
readonly geolocation: Geolocation
}

interface Geolocation {
clearWatch(watchId: number): void
getCurrentPosition(successCallback: PositionCallback, errorCallback?: PositionErrorCallback | null, options?: PositionOptions): void
watchPosition(successCallback: PositionCallback, errorCallback?: PositionErrorCallback | null, options?: PositionOptions): number
}

interface PositionCallback {
(position: GeolocationPosition): void
}

interface PositionErrorCallback {
(positionError: GeolocationPositionError): void
}

interface PositionOptions {
enableHighAccuracy?: boolean
maximumAge?: number
timeout?: number
}

interface GeolocationPosition {
readonly coords: GeolocationCoordinates
readonly timestamp: EpochTimeStamp
}

interface GeolocationPositionError {
readonly code: number
readonly message: string
readonly PERMISSION_DENIED: 1
readonly POSITION_UNAVAILABLE: 2
readonly TIMEOUT: 3
}

interface GeolocationCoordinates {
readonly accuracy: number
readonly altitude: number | null
readonly altitudeAccuracy: number | null
readonly heading: number | null
readonly latitude: number
readonly longitude: number
readonly speed: number | null
}

链接

File System API

File System API 允许使用内置文件系统,包含读取、修改和移除文件,扩展的 File System Access API 允许访问本地文件系统

  • FileSystemHandle 接口作为文件句柄或目录句柄的通用接口
  • FileSystemFileHandle 接口作为文件句柄的接口
  • FileSystemDirectoryHandle 接口作为目录句柄的接口
  • FileSystemSyncAccessHandle 接口作为同步访问句柄的接口
  • FileSystemWritableFileStream 接口作为读写本地文件流的接口
  • StorageManager 接口上的 getDirectory() 方法用于获取 Origin Private File System 的根目录句柄

通常而言,File System API 需要用户明确的许可,但 OPFS —— Origin Private File System 机制除外。

通常 File System API 的大多数操作是异步的,支持同步的 FileSystemSyncAccessHandle 接口仅在 Web Worker 内可用且仅允许使用于 OPFS。

初始化

获取 OPFS 的根目录句柄

使用 StorageManager 接口的 getDirectory() 方法获取 OPFS 的根目录句柄

返回一个 Promise 的 FileSystemDirectoryHandle 对象

并在用户代理无法使用请求的文件目录建立本地 OPFS 索引时抛出 SecurityError 异常

文件及目录操作

通过 FileSystemHandle 接口进行文件目录相关的操作,该接口是 FileSystemFileHandle 接口与 FileSystemDirectoryHandle 接口的父接口

句柄类型

FileSystemHandle 接口的 kind 属性返回一个字符串枚举值,代表句柄的类型

当当前句柄为 FileSystemFileHandle 时,返回 'file'

当当前句柄为 FileSystemDirectoryHandle 时,返回 'directory'

句柄名称

FileSystemHandle 接口的 name 属性返回一个字符串,代表句柄对应的文件或目录的名称

句柄比较

FileSystemHandle 接口的 isSameEntry() 方法判断当前句柄与传入的句柄是否指向同一个文件或目录

方法接收一个 FileSystemHandle

方法返回一个 Promise 的 boolean

权限操作

FileSystemHandle 接口的 queryPermission() 方法用于枚举当前句柄的指定权限

FileSystemHandle 接口的 requestPermission() 方法用于请求当前句柄的指定权限

方法均支持传入一组可选的描述符,唯一 mode 参数可以为 'read''readwrite' 之一,默认为 'read'

方法均返回一个 Promise 的 PermissionStatus 接口实例

文件操作

通过 FileSystemFileHandle 接口进行文件相关的操作,该接口继承自 FileSystemHandle 接口

获取文件

FileSystemFileHandle 接口的 getFile() 方法可以用于读取文件相关信息及用于网络传输

返回一个 Promise 的 File 对象

抛出一个 NotAllowedError 若未授予访问权限

获取同步访问句柄

FileSystemFileHandle 接口的 createSyncAccessHandle() 方法可以用于同步读写文件内容,但仅允许在专属 Worker 内部使用,且目前仅适用于 OPFS 机制

返回一个 Promise 的 FileSystemSyncAccessHandle 对象

抛出一个 NotAllowedError 若未授予访问权限

抛出一个 NoModificationAllowedError 若无法建立文件锁

抛出一个 InvalidStateError 若句柄无法表示 OPFS 中的文件

获取可写文件流

FileSystemFileHandle 接口的 createWritable() 方法可以用于修改文件内容

可以传入一组可选的配置项,唯一选项 keepExistingData 指定

返回一个 Promise 的 FileSystemWritableFileStream 对象

抛出一个 NotAllowedError 若未授予访问权限

目录操作

通过 FileSystemDirectoryHandle 接口进行目录相关的操作,该接口继承自 FileSystemHandle 接口

目录遍历

FileSystemDirectoryHandle 接口支持异步遍历,包含 [@@asyncIterator]() 以及 entries()keys()values() 等方法

获取路径

FileSystemDirectoryHandle 接口的 resolve() 方法用于获取当前句柄到指定句柄的相对路径

需要传入一个 FileSystemHandle,代表目标句柄

返回一个 Promise 的字符串数组或 null

获取子目录

FileSystemDirectoryHandle 接口的 getDirectoryHandle() 方法用于获取当前目录下的指定名称的子目录的句柄

需要传入一个字符串参数,代表目录的名称,与 FileSystemHandle.name 相符

可以传入一组配置项,唯一参数 create 为一个布尔值,指定目录不存在情况下是否创建目录,默认值为 false

返回一个 Promise 的 FileSystemDirectoryHandle 对象

抛出一个 TypeErrorname 参数不是字符串或为非法的文件系统名称

抛出一个 TypeMismatchError 若匹配到的为文件而非目录

抛出一个 NotFoundError 若未找到目录且 create 选项设定为 false

抛出一个 NotAllowedError 若未授予访问权限

获取子文件

FileSystemDirectoryHandle 接口的 getFileHandle() 方法用于获取当前目录下的指定名称的子文件的句柄

需要传入一个字符串参数,代表目录的名称,与 FileSystemHandle.name 相符

可以传入一组配置项,唯一参数 create 为一个布尔值,指定目录不存在情况下是否创建目录,默认值为 false

返回一个 Promise 的 FileSystemFileHandle 对象

抛出一个 TypeErrorname 参数不是字符串或为非法的文件系统名称

抛出一个 TypeMismatchError 若匹配到的为目录而非文件

抛出一个 NotFoundError 若未找到文件且 create 选项设定为 false

抛出一个 NotAllowedError 若未授予访问权限

删除子目录或子文件

FileSystemDirectoryHandle 接口的 removeEntry() 方法用于删除当前目录下的指定名称的子目录或子文件的句柄

需要传入一个字符串参数,代表目录的名称,与 FileSystemHandle.name 相符

可以传入一组配置项,唯一参数 recursive 为一个布尔值,指定是否递归删除,默认值为 false

返回一个 Promise 的 undefined

抛出一个 TypeErrorname 参数不是字符串或为非法的文件系统名称

抛出一个 InvalidModificationError 若目标为目录,并且包含子文件或子目录,并且 recursive 设置为 false

抛出一个 NotFoundError 若未找到文件或目录

抛出一个 NotAllowedError 若未授予访问权限

文件读取

文件读取通过 FileSystemFileHandle 接口的 getFile() 方法获取到对应的 File 实例实现

文件修改

文件修改通过 FileSystemFileHandle 接口的 createWritable() 方法获取到对应的 FileSystemWritableFileStream 实例实现

FileSystemWritableFileStream 接口继承自 WritableStream 接口

FileSystemWritableFileStream 接口的更改不会立即反映到实际的文件上,仅在关闭流之后才会同步其产生的更改;原因是对流的更改,至少会存储到一个临时文件中,仅在流关闭之后,才会将更改同步到实际的文件中

移动指针

使用 FileSystemWritableFileStream 接口的 seek() 方法移动文件指针的位置

需要传入一个正整数 position 参数,代表文件指针的位置

返回一个 Promise

抛出一个 NotAllowedError 若未授予访问权限

抛出一个 TypeErrorposition 参数不是正整数或未传递

文件写入

使用 FileSystemWritableFileStream 接口的 write() 方法用于向文件中写入内容

可以传入一个 data 参数,代表需要写入文件的内容,可以是 ArrayBuffer TypedArray DataView Blobstring

亦可以传入一组配置项:

type 选项传入一组字符串枚举,指定操作的模式,可以是 "write" "seek""truncate"

data 选项,代表需要写入文件的内容,可以是 ArrayBuffer TypedArray DataView Blobstring,在 "write" 模式下是必须的

position 选项,代表需要移动的文件指针的目标位置,是一个正整数,在 "seek" 模式下是必须的;同样可以在 "write" 模式下使用,此时代表写入内容的目标位置

size 选项,代表需要文件流的大小,是一个正整数,在 "truncate" 模式下是必须的

返回一个 Promise

抛出一个 NotAllowedError 若未授予访问权限

抛出一个 TypeError 若传入参数非法

抛出一个 InvalidStateErrorposition 选项的值超出文件大小

文件尺寸修改

使用 FileSystemWritableFileStream 接口的 truncate() 方法改变文件的尺寸;方法可能会改变文件指针的位置

需要传入一个正整数 size 参数,代表目标的文件尺寸;若参数超出原有尺寸,则扩大当前文件并使用空内容填充扩大的部分,反之会裁剪当前文件

返回一个 Promise

抛出一个 NotAllowedError 若未授予访问权限

抛出一个 TypeErrorsize 参数不是正整数或未传递

文件同步读写

文件同步读写通过 FileSystemFileHandle 接口的 createSyncAccessHandle() 方法获取到对应的 FileSystemSyncAccessHandle 实例实现

FileSystemSyncAccessHandle 实例仅支持在专属 Worker 中使用,且目前仅适用于 OPFS 机制

因为其无需进行权限检查,其相对而言具有更好的性能

创建 FileSystemSyncAccessHandle 实例会创建与之对应的文件锁,阻止对该文件创建其他的 FileSystemSyncAccessHandle 实例或 FileSystemWritableFileStream 实例,直到 FileSystemSyncAccessHandle 实例被销毁

FileSystemSyncAccessHandle 接口的 read() 方法读取文件内容

方法传入一个 buffer 参数,可以是 ArrayBuffer SharedArrayBuffer TypedArrayDataView,代表用于存储读取文件内容的缓存区

方法支持传入一个可选的配置项:其 at 参数指定开始读取文件内容的起始位置

方法返回一个正整数,代表读取的文件内容的字节数

方法在若对应的句柄已关闭的情况下,抛出一个 InvalidStateError

FileSystemSyncAccessHandle 接口的 write() 方法向文件写入内容

方法传入一个 buffer 参数,可以是 ArrayBuffer SharedArrayBuffer TypedArrayDataView,代表将用于写入的文件内容

方法可以传入一个可选的配置项:其 at 参数指定开始写入文件内容的起始位置

方法返回一个正整数,代表写入的文件内容的字节数

方法在若对应的句柄已关闭的情况下,抛出一个 InvalidStateError

读取尺寸

FileSystemSyncAccessHandle 接口的 getSize() 方法返回文件的尺寸

方法返回一个正整数,代表文件内容的字节数

方法在若对应的句柄已关闭的情况下,抛出一个 InvalidStateError

更改尺寸

FileSystemSyncAccessHandle 接口的 truncate() 方法用于更改文件的尺寸

方法传入一个 newSize 参数,需要是一个正整数,代表将更改的文件的目标大小

方法在若对应的句柄已关闭的情况下,抛出一个 InvalidStateError

方法在若对应的句柄已关闭的情况下,抛出一个 InvalidStateError

刷新缓冲区

FileSystemSyncAccessHandle 接口的 flush() 方法用于将缓冲的更改同步至存储,通常只在特定时间段需要将缓冲的更改同步至存储时使用,否则可以让底层自行处理

关闭句柄

FileSystemSyncAccessHandle 接口的 close() 方法用于关闭当前句柄,释放文件锁

类型

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
52
53
54
55
56
57
interface FileSystemHandle {
readonly kind: FileSystemHandleKind
readonly name: string
isSameEntry(other: FileSystemHandle): Promise<boolean>
}

interface FileSystemFileHandle extends FileSystemHandle {
readonly kind: 'file'
createSyncAccessHandle(): Promise<FileSystemSyncAccessHandle>
createWritable(options?: FileSystemCreateWritableOptions): Promise<FileSystemWritableFileStream>
getFile(): Promise<File>
}

interface FileSystemDirectoryHandle extends FileSystemHandle {
readonly kind: 'directory'
getDirectoryHandle(name: string, options?: FileSystemGetDirectoryOptions): Promise<FileSystemDirectoryHandle>
getFileHandle(name: string, options?: FileSystemGetFileOptions): Promise<FileSystemFileHandle>
removeEntry(name: string, options?: FileSystemRemoveOptions): Promise<void>
resolve(possibleDescendant: FileSystemHandle): Promise<string[] | null>
}

interface FileSystemWritableFileStream extends WritableStream {
seek(position: number): Promise<void>
truncate(size: number): Promise<void>
write(data: FileSystemWriteChunkType): Promise<void>
}

interface FileSystemSyncAccessHandle {
close(): void;
flush(): void;
getSize(): number;
read(buffer: AllowSharedBufferSource, options?: FileSystemReadWriteOptions): number;
truncate(newSize: number): void;
write(buffer: AllowSharedBufferSource, options?: FileSystemReadWriteOptions): number;
}

interface FileSystemCreateWritableOptions {
keepExistingData?: boolean
}

interface FileSystemGetDirectoryOptions {
create?: boolean
}

interface FileSystemGetFileOptions {
create?: boolean
}

interface FileSystemReadWriteOptions {
at?: number
}

interface FileSystemRemoveOptions {
recursive?: boolean
}

type FileSystemWriteChunkType = BufferSource | Blob | string | WriteParams

链接


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